php-meminfo: Objects that are still in memory but not shown by php-meminfo

I tried using php-meminfo in finding out why in a specific case PDO connections were being kept open. PDO connections only close when they end up out of scope without a refcount so I kinda knew where to look.

After addressing some issues ( https://github.com/BitOne/php-meminfo/pull/62 ) and even adding a little object store dumper to this extension (see paste below) I noticed that even though php-meminfo wasn’t showing me these instances, they were still actively in memory.

This problem occured in a Laravel+Laravel Doctrine project. I suspect that these PDO instances might be referenced in closures somewhere? But maybe they’re referenced in a different call stack? Is there any way we could have php-meminfo actually find references to these objects somehow?

Attachment, overly simple object_store_dump():

PHP_FUNCTION(object_store_dump)
{
        zend_object **obj_ptr, **end, *obj;

        if (EG(objects_store).top <= 1) {
                return;
        }

        end = EG(objects_store).object_buckets + 1;
        obj_ptr = EG(objects_store).object_buckets + EG(objects_store).top;

        do {
                obj_ptr--;
                obj = *obj_ptr;

                if (IS_OBJ_VALID(obj)) {
                        php_printf("object: %s: %d\n", obj->ce->name->val, obj->handle );

                        if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
                                php_printf("- DESTRUCTOR NOT CALLED\n");
                        }

                        if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
                                php_printf("- FREE NOT CALLED\n");
                        }

                }
        } while (obj_ptr != end);
}

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 17 (10 by maintainers)

Commits related to this issue

Most upvoted comments

The way I understand it, php-meminfo currently works by walking the current call stack and inspecting the symbol tables available for each stack frame. Any array and object that it encounters is inspected in detail. That works for many cases, but I think it wont find things like:

  • Variables bound in closures
  • Variables used in generators where execution is currently out of the generator.
  • Objects in a cyclic-reference (as mentioned above). But these might be found by inspecting the object-store.
  • memory use by extensions that get tracked by the zend memory allocator ( I think allocating a zval will do that? Not sure tho ) but which are never exposed to the PHP executor and are hence invisible for php-meminfo.