Skip to content

Rerun GC if destructors encountered #5581

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

Closed
wants to merge 1 commit into from
Closed

Conversation

nikic
Copy link
Member

@nikic nikic commented May 15, 2020

Since PHP 7.4 objects that have a destructor require two GC runs to be collected. Currently the collection is delayed to the next automatic GC run. However, in some cases this may result in a large increase in memory usage, as in one of the cases of https://bugs.php.net/bug.php?id=79519. I have also had some reports (though I don't remember from where) there code depended on gc_collect_cycles() destroying everything in one call.

This patch will automatically rerun GC if destructors were encountered. I think this should not have much cost, because it is very likely that objects on which the destructor has been called really are garbage, so the extra GC run should not be doing wasted work.

@nikic
Copy link
Member Author

nikic commented May 15, 2020

@dstogov Do you think this makes sense?

It seems like our minimum GC threshold of 10000 is also problematic for some workloads, and we probably should allow going below it.

Zend/zend_gc.c Outdated
@@ -1476,6 +1479,7 @@ ZEND_API int zend_gc_collect_cycles(void)
* short of rerunning full GC tracing. What we do instead is to only run
* destructors at this point, and leave the actual freeing of the objects
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment should also be updated to avoid confusion when reading this later. Something along the lines of "only run destructors at this point, then automatically re-run GC at most once after calling the destructors."

@dstogov
Copy link
Member

dstogov commented May 18, 2020

@dstogov Do you think this makes sense?

I think, this shouldn't make a big problem. Did you estimate the impact of the patch on something GC hungry? e.g. PHP-Parser, composer,...?

It seems like our minimum GC threshold of 10000 is also problematic for some workloads, and we probably should allow going below it.

10000 was selected to run most web applications without GC overhead. I'm not sure what kind of loads do you mean and if we should decries GC threshold. Probably, better to trigger GC when memory_limit is exhausted.

@nikic
Copy link
Member Author

nikic commented Jun 25, 2020

I think, this shouldn't make a big problem. Did you estimate the impact of the patch on something GC hungry? e.g. PHP-Parser, composer,...?

I checked that there is no visible impact on PHP-Parser / Composer. However, it's probably not very meaningful, because both projects don't really use __destruct.

It seems like our minimum GC threshold of 10000 is also problematic for some workloads, and we probably should allow going below it.

10000 was selected to run most web applications without GC overhead. I'm not sure what kind of loads do you mean and if we should decries GC threshold. Probably, better to trigger GC when memory_limit is exhausted.

To be clear, I'm not suggesting to lower the default of 10000, just to allow going below it if we find that GC is very "effective". I agree though that triggering GC when we run close to memory_limit may be a better starting point.

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

Successfully merging this pull request may close these issues.

3 participants