php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67840 Object is not destructed after disassigned even if refcount was 1
Submitted: 2014-08-14 08:36 UTC Modified: 2014-08-16 20:48 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:2 (100.0%)
From: strate at yandex dot ru Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.5.15 OS: Ubuntu
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: strate at yandex dot ru
New email:
PHP Version: OS:

 

 [2014-08-14 08:36 UTC] strate at yandex dot ru
Description:
------------
If we store reference to $this inside object's constructor to external variable, object will not destructed.

As you can see object A destructed only at the end of script, but refcount was equals to 1 right before invalidating variable, containing object.

Seems to be bug, because if we will store reference to variable, containing object outside the constructor, everything works as expected.

Test script:
---------------
https://gist.github.com/Strate/b037e529ee752489a45f

Expected result:
----------------
php refcounttest.php
b: (refcount=2, is_ref=1)=class B {  }
Expecting object destruction ... Object B destructed! Expectation finished
a: (refcount=1, is_ref=0)=class A {  }
 Expecting object destruction ... Object A destructed!  Expectation finished
End of script

Actual result:
--------------
php refcounttest.php
b: (refcount=2, is_ref=1)=class B {  }
Expecting object destruction ... Object B destructed! Expectation finished
a: (refcount=1, is_ref=0)=class A {  }
 Expecting object destruction ...  Expectation finished
End of script
Object A destructed!

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-08-16 20:48 UTC] bwoebi@php.net
-Status: Open +Status: Not a bug
 [2014-08-16 20:48 UTC] bwoebi@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

B::$instances[spl_object_hash($b)] = &$b;
// ...
$b = false;

In this case, B::$instances[$the_hash] will be false ($b being a referencing variable [it's the variable reference which is assigned, not an object reference]) too, so there's no pointer outside nor inside the object to the object. It'll be destructed.

If you'd have written:
B::$instances[spl_object_hash($b)] = $b; // note: no reference

You'd observe the same behaviour as in A.


In case of A, you assign the reference to $this, but $this won't be changed, whether it's a reference or not makes no difference. So it still will have some pointer inside the object to the object itself - it'll only be destructed when the garbage collector fires.

---

Some note about your refcounts... Objects have a separate refcounter, the variable outside the object, holding it, is not the same one than $this!
 [2014-08-18 08:02 UTC] strate at yandex dot ru
bwoebi@php.net, thank you for explanation!
But I missed one thing - you tell that $this destructed only when gc fired. But this should mean that all objects should be destroyed only on gc hit, because all objects has cycle references, yes? But, in my example, object of B class destructed right after setting $b to false.
-----
About refcounter of object. Is there any documentation about it? Because I am trying to found memory leaks in my application and I am really can not understand why my objects are not destroyed even with refcount == 1.
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Tue Oct 06 08:00:02 2026 UTC