Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$_cache variable significantly increases memory usage #25

Closed
pohnean opened this issue May 29, 2013 · 5 comments
Closed

$_cache variable significantly increases memory usage #25

pohnean opened this issue May 29, 2013 · 5 comments

Comments

@pohnean
Copy link

pohnean commented May 29, 2013

I'm having a huge memory leak issue when iterating through large numbers of ActiveRecords with NestedSetBehavior attached. This is because of the circular reference that is created behaviors are added to ActiveRecord (see yiisoft/yii#1329).

To test this issue:

Create 500 objects with NestedSetBehavior attached and log the memory usage before and after.

$max = 500;

for ($i = 0; $i< $max; $i++) {
    $model = new Model();
 }

The results:

  • Before: 8.75MB
  • After: 100.25MB

The Problem:

I found out that the $_cache variable used in the afterConstruct() and afterFind() methods were causing a huge increase in memory usage and are not released even after unsetting $model due to circular referencing.

Solution:

  1. Add this function to NestedSetBehavior:
    public function detach($owner)
    {
    // free up memory when detachBehavior() is called.
    self::$_cached = null;
    self::$_c = null;

        parent::detach($owner);
    

    }

  2. Call $model->detachBehaviors();
    Results:
    Before: 8.75MB
    After: 12MB

@creocoder
Copy link
Member

I think we will solve issue by other (__destructor()) way. Thanks for catch.

@pohnean
Copy link
Author

pohnean commented May 31, 2013

unfortunately __destruct() is only called when the script ends. Thus PHP's garbage collection is not triggered to free up the memory. the only way is to manually remove the circular reference by calling detachBehavior().

@creocoder
Copy link
Member

Yes. But i'm against to override detach(). Framework should call destructor on detachBehavior() if behavior have it. So its framework issue. Working on this.

@cebe
Copy link
Member

cebe commented May 31, 2013

Working on this.

@creocoder what are you trying to do about it? PHP should be aware of cycle references but as mentioned in yiisoft/yii#1329 (comment) there seems to be a bug in php.

@creocoder
Copy link
Member

@cebe So solution is:

foreach ($models as $model) {
    $model->detachBehaviors();
}
gc_collect_cycles();

? And we should not do anything?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants