asmblah / heap-walker
PHP用户空间堆遍历器
v1.1.0
2021-10-08 00:31 UTC
Requires (Dev)
- phpspec/prophecy-phpunit: ^2.0
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^4.10
This package is auto-updated.
Last update: 2024-08-30 01:20:35 UTC
README
尽可能遍历用户空间堆,寻找给定FQCN(完全限定类名)的实例。
这有助于确定给定对象被引用的位置,以帮助解决内存泄漏问题。
用法
安装
composer require --dev asmblah/heap-walker
使用
<?php // ... $heapWalk = new HeapWalk(); // Find all instances of Item and how to reach them. $pathSets = $heapWalk->getInstancePathSets([Item::class]); // Inspect the result as needed.
完整示例
<?php use Asmblah\HeapWalk\HeapWalk; use Asmblah\HeapWalk\Result\Path\InstancePathSet; require_once __DIR__ . '/vendor/autoload.php'; class Item { public $description; public function __construct($description) { $this->description = $description; } } class Bag { // Note that visibility is ignored. private static $items = []; public static function init() { self::$items[] = new Item('a cabbage'); } } Bag::init(); $heapWalk = new HeapWalk(); // Find all instances of Item and how to reach them. $pathSets = $heapWalk->getInstancePathSets([Item::class]); // Inspect the result as needed. assert(count($pathSets) === 1); assert($pathSets[0] instanceof InstancePathSet); assert(count($pathSets[0]->getPaths()) === 1); assert($pathSets[0]->getPaths()[0]->toString() === 'Bag::$items[0]'); assert($pathSets[0]->getPaths()[0]->getEventualValue() instanceof Item); assert($pathSets[0]->getPaths()[0]->getEventualValue()->description === 'a cabbage');
注意事项与限制
-
除了全局作用域之外的作用域不会被完全检查;只有通过使用
debug_backtrace()
捕获它们的参数。 -
暂停的生成器的局部作用域不可访问。例如,如果暂停的生成器内部声明了一个没有其他引用的迭代变量
$i
,那么它将不会被找到。 -
如果捕获的对象是另一个未捕获对象的子代,那么(目前)递归处理意味着只记录通过未捕获对象到达捕获对象的第一个路径。例如,在Symfony容器中的服务将通过
$kernel->bundles->...->container[...]
显示,而不会也通过$kernel->container[...]
显示。 -
PHP对象之间的内部引用,这些引用不会暴露给用户空间,是无法发现的。例如,
PDOStatement
对其PDOConnection
有一个内部强引用,但是无法从PDOStatement
访问PDOConnection
。可以使用uopz扩展挂钩PDOConnection->prepare(...)
并将其从PDOStatement
链接回来(例如,在未来的插件中),但是必须小心处理以避免阻止PDOConnection
被GC。