Re: [PHP] unset and circular references

2008-06-27 Thread Thijs Lensselink

Quoting Abu Warez [EMAIL PROTECTED]:


Hi,

I'm using php 5.2.1 on an Ubuntu machine.

I have the following class diagram (observer pattern):

+-+ +-+ +-+
| class A |#-| class B | -| interface C |
| | +-+ | |
| |---|| |
+-+ +-+

in my case class A, the creator of class B, is also the class to observe
for class B. The following code implements the above diagram:

?php

interface C
{
}


class B
{
var $m_ObsC;

public function __construct( C $p_ObsC )
{
$this-m_ObsC = $p_ObsC;
}

public function __destruct()
{
echo B::destruct called br;
}
}

class A implements C
{
var $m_b;

public function __construct()
{
$this-m_b = new B( $this );
}

public function __destruct()
{
echo A::destruct called br;
}
}

$a = new A();

unset( $a );

echo br-end-of-scriptbr;

?


the output of the above code is:

-end-of-script
A::destruct called
B::destruct called

So actually the memory used by object $a is freed only after the script
ends and NOT when unset was called. Now this is a big problem for me,
because i need to free the memory when I call unset and not after the
script ends else php runs out of memory in my real application. Object $a
is not referenced by any other object. I also tried with:

$this-m_b = new B( $this );

but the result is the same.

Any clue how to determine php tho free the memory when unset is called and
not after the script ends?

Thanks,

Abu




I think this happens because there is still a reference to the B object.
According to the manual :

The destructor method will be called as soon as all references to a  
particular object are removed or when the object is explicitly  
destroyed or in any order in shutdown sequence.


So as long as A has a reference to B the __destructor will not be called.


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] unset and circular references

2008-06-27 Thread Abu Warez



--- On Fri, 6/27/08, Thijs Lensselink [EMAIL PROTECTED] wrote:

 From: Thijs Lensselink [EMAIL PROTECTED]
 Subject: Re: [PHP] unset and circular references
 To: php-general@lists.php.net
 Date: Friday, June 27, 2008, 5:21 PM
 Quoting Abu Warez [EMAIL PROTECTED]:
 
  Hi,
 
  I'm using php 5.2.1 on an Ubuntu machine.
 
  I have the following class diagram (observer pattern):
 
  +-+ +-+
 +-+
  | class A |#-| class B |
 -| interface C |
  | | +-+ | 
|
  | |---||  
   |
  +-+
 +-+
 
  in my case class A, the creator of class B, is also
 the class to observe
  for class B. The following code implements the above
 diagram:
 
  ?php
 
  interface C
  {
  }
 
 
  class B
  {
  var $m_ObsC;
 
  public function __construct( C $p_ObsC )
  {
  $this-m_ObsC = $p_ObsC;
  }
 
  public function __destruct()
  {
  echo B::destruct called
 br;
  }
  }
 
  class A implements C
  {
  var $m_b;
 
  public function __construct()
  {
  $this-m_b = new B( $this );
  }
 
  public function __destruct()
  {
  echo A::destruct called
 br;
  }
  }
 
  $a = new A();
 
  unset( $a );
 
  echo
 br-end-of-scriptbr;
 
  ?
 
 
  the output of the above code is:
 
  -end-of-script
  A::destruct called
  B::destruct called
 
  So actually the memory used by object $a is freed only
 after the script
  ends and NOT when unset was called. Now this is a big
 problem for me,
  because i need to free the memory when I call unset
 and not after the
  script ends else php runs out of memory in my real
 application. Object $a
  is not referenced by any other object. I also tried
 with:
 
  $this-m_b = new B( $this );
 
  but the result is the same.
 
  Any clue how to determine php tho free the memory when
 unset is called and
  not after the script ends?
 
  Thanks,
 
  Abu
 
 
 
 I think this happens because there is still a reference to
 the B object.
 According to the manual :
 
 The destructor method will be called as soon as all
 references to a  
 particular object are removed or when the object is
 explicitly  
 destroyed or in any order in shutdown sequence.
 
 So as long as A has a reference to B the __destructor will
 not be called.
 
 
 --
 PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php


  


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] unset and circular references

2008-06-27 Thread Abu Warez
--- On Fri, 6/27/08, Thijs Lensselink [EMAIL PROTECTED] wrote:
 From: Thijs Lensselink [EMAIL PROTECTED]
 Subject: Re: [PHP] unset and circular references
 To: php-general@lists.php.net
 Date: Friday, June 27, 2008, 5:21 PM
 Quoting Abu Warez [EMAIL PROTECTED]:



 I think this happens because there is still a reference to
 the B object.
 According to the manual :

 The destructor method will be called as soon as all
 references to a 
 particular object are removed or when the object is
 explicitly 
 destroyed or in any order in shutdown sequence.

 So as long as A has a reference to B the __destructor will
 not be called.

I think you mean: As long as B has a ref to A (which, indeed, creates B),
the destructor of A will not be called.
I agree with that, but in this case the garbage collector should detect
that the reference to object $a is from an object $m_b which is created (and 
maintained) again by the first object $a. In other words, if object $a is not 
needed then its member $m_b (which has a reference to $a) is not needed 
neither. So in this case, in my opinion, if one wants to destory object $a then 
the reference from $m_b to $a should not count.

This issue is really frustrating because because in my code I have something 
like (where $a is of type class A):

for ( $id ... )
{
$a = daoMyClass-LoadById( $id );
 modify $a ...
/* persist modified $a */
daoMyClass-Update( $a );
unset( $a );
}

unset, as stated, does not destroy $a and all the loaded $a's remain in
memory until the script ends. Rising the memory limit is not a solution
because the count of $a objects grows between script calls. Any ideas?

Thx,
Abu



  


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] unset and circular references

2008-06-27 Thread T Lensselink
Abu Warez wrote:
 --- On Fri, 6/27/08, Thijs Lensselink [EMAIL PROTECTED] wrote:
   
 From: Thijs Lensselink [EMAIL PROTECTED]
 Subject: Re: [PHP] unset and circular references
 To: php-general@lists.php.net
 Date: Friday, June 27, 2008, 5:21 PM
 Quoting Abu Warez [EMAIL PROTECTED]:

 

   
 I think this happens because there is still a reference to
 
  the B object.
   
 According to the manual :

 The destructor method will be called as soon as all
 references to a 
 particular object are removed or when the object is
 explicitly 
 destroyed or in any order in shutdown sequence.

 So as long as A has a reference to B the __destructor will
 not be called.
 

 I think you mean: As long as B has a ref to A (which, indeed, creates B),
 the destructor of A will not be called.
   
My bad. that's what i meant.
 I agree with that, but in this case the garbage collector should detect
 that the reference to object $a is from an object $m_b which is created (and 
 maintained) again by the first object $a. In other words, if object $a is not 
 needed then its member $m_b (which has a reference to $a) is not needed 
 neither. So in this case, in my opinion, if one wants to destory object $a 
 then the reference from $m_b to $a should not count.
   
That would still leave a reference from B to A. That's why it doesn't
get unset. If you unset B before unsetting A the problem is resolved.
 This issue is really frustrating because because in my code I have something 
 like (where $a is of type class A):

 for ( $id ... )
 {
 $a = daoMyClass-LoadById( $id );
  modify $a ...
 /* persist modified $a */
 daoMyClass-Update( $a );
 unset( $a );
 }

 unset, as stated, does not destroy $a and all the loaded $a's remain in
 memory until the script ends. Rising the memory limit is not a solution
 because the count of $a objects grows between script calls. Any ideas?

 Thx,
 Abu



   


   


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php