Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] Don't add simple objects to GC's roots

Posted by Nicolas Grekas 
Nicolas Grekas
[PHP-DEV] Don't add simple objects to GC's roots
July 26, 2017 05:00PM
Hi,

I'm hitting more and more the GC threshold in projects I work on (the "10k
roots" one), leading to high CPU usage. Usually, the GC finds nothing to
clean, so this is just a waste of CPU.

By being super light and fast, objects are nice for many tasks, and the
trend is to use them all over the place, e.g. as nodes when parsing a PHP
AST.

There is a way to work around: just call gc_disable(). But this means
dealing with side effects of the engine in userland. Moreover, this also
means leaking memory, since meanwhile roots are not populated.

I was wondering: does it exist some light algorithm that could prevent
hitting the threshold that often?
E.g. in my previous example, AST nodes are created free of any circular
refs. Would it be possible to add them (and any objects really) to GC's
roots list *only* when userland does something that *might* create a
circular ref? (e.g. setting a property to a non scalar? or something more
clever?)

Just raising the topic, as unfortunately I wouldn't be able to do more.

Thanks for considering,
Nicolas
Hi,
> On 26 Jul 2017, at 22:57, Nicolas Grekas <[email protected]> wrote:
>
> There is a way to work around: just call gc_disable(). But this means
> dealing with side effects of the engine in userland. Moreover, this also
> means leaking memory, since meanwhile roots are not populated.

Maybe we could make gc_disable accept one reference zval as parameter, and
clear the GC_COLLECTABLE flag of zval.value->gc.u.v.flags. So, this zval
will never be put into gc root list.



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
江湖大虾仁
Re: [PHP-DEV] Don't add simple objects to GC's roots
July 27, 2017 06:20PM
On 26 Jul 2017, at 22:57, 吕海涛 <[email protected]> wrote:>> There is a way to work around: just call gc_disable(). But this means
>> dealing with side effects of the engine in userland. Moreover, this also
>> means leaking memory, since meanwhile roots are not populated.

>Maybe we could make gc_disable accept one reference zval as parameter, and
>clear the GC_COLLECTABLE flag of zval.value->gc.u.v.flags. So, this zval
>will never be put into gc root list.



I don't think it's a good idea to expose such an internal detail to userland. The more we expose, the more limits we will face in the future if we want to make some changes.


best regards,
CHU Zhaowei
Hi, internals,

> On 26 Jul 2017, at 22:57, Nicolas Grekas <[email protected]> wrote:
>
> I'm hitting more and more the GC threshold in projects I work on (the "10k
> roots" one), leading to high CPU usage. Usually, the GC finds nothing to
> clean, so this is just a waste of CPU.

More and more php frameworks use object/array as an global container to store
config, and these container variable will be used every where, but seldom
introduce the circular reference. Apart from this, these container variable
will always be a huge tree, so iterate them will lead to high CPU usage.

> There is a way to work around: just call gc_disable(). But this means
> dealing with side effects of the engine in userland. Moreover, this also
> means leaking memory, since meanwhile roots are not populated.

In PHP-7.2, the GC_COLLECTABLE flag has been moved into the gc struct, and
this make it possible to prevent gc trace for certain zval.

So I propose to make the gc_disable function accept one zval reference as
parameter. And if gc_disable get that zval, gc_disable just drop the zval’s
GC_COLLECTABLE flag, which will hint the PHP gc not to trace that zval.

Here is my patch https://github.com/php/php-src/pull/2665/files, and a demo,

<?php
function hi($a)
{
return $a->name;
}

$a = new stdclass;
$a->name = 'foo';

gc_disable($a);

hi($a); // these will change the refcount of $a, but never trace gc


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Andreas Treichel
Re: [PHP-DEV] Don't add simple objects to GC's roots
July 30, 2017 12:30PM
Hi,

> So I propose to make the gc_disable function accept one zval reference as
> parameter. And if gc_disable get that zval, gc_disable just drop the zval’s
> GC_COLLECTABLE flag, which will hint the PHP gc not to trace that zval.

i dont know if this is a good idea or not. But for the "s" in solid,
create a new function like gc_exclude to exclude variables from the
garbage collector and do not add a parameter to gc_disable.


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Sorry, only registered users may post in this forum.

Click here to login