Thanks for the example. Now I understand the root cause. There is a similar bug 
report(https://bugs.php.net/bug.php?id=74938) for anonymous function. I thought 
it leaked for the same reason, but now I think I’m wrong. We don’t have to 
create new classes for them since they are all instances of Closure class, and 
it’s not possible to create opaque reference for functions.  __FUNCTION__ 
returns “{closure}”. Could you take a look?

 

Back to the anonymous class, I’m thinking if we can have any workaround for 
this issue, otherwise it will be a huge problem if someone wants to write 
applications running for a long time. It will be a memory leak that cannot be 
fixed in userland code unless he decides to drop anonymous class at all. Since 
most of the use cases should not have opaque references, can we add a flag in 
zval to indicate if an object has this kind of reference? The number of methods 
to create such opaque references should be limited. __CLASS__, get_class(), 
reflections, clone. Did I miss any other way? With the help of this flag, we 
are able to know if it’s safe to remove the class definition during destruction.

 

Regards,

CHU Zhaowei

 

From: Nikita Popov <nikita....@gmail.com> 
Sent: Saturday, June 29, 2019 3:58 PM
To: CHU Zhaowei <m...@jhdxr.com>
Cc: Stanislav Malyshev <smalys...@gmail.com>; Benjamin Morel 
<benjamin.mo...@gmail.com>; PHP Internals <internals@lists.php.net>
Subject: Re: [PHP-DEV] Memory leak in eval()'d code

 

On Sat, Jun 29, 2019 at 9:07 AM CHU Zhaowei <m...@jhdxr.com 
<mailto:m...@jhdxr.com> > wrote:

I think we missed the point here. Clousre, or anonymous class, should not be 
considered as normal class. We expect normal class existing once we declare it 
till end of script. However, for anonymous class, it's usually used within 
certain scope, so not only the instances, the class itself should be included 
in the GC as well. 
I guess the problem here is we didn't GC the space for definition of anonymous 
classes.

Regards,
CHU Zhaowei

 

As Johannes already pointed out, we cannot garbage collect anonymous class 
definitions due to the existence of opaque references. A simple example of code 
that currently works:

 

    $obj = eval('return new class {}');

    $class = get_class($obj); // create opaque reference

    unset($obj); // drop last direct reference

    $obj = new $class;

 

In the end, an anonymous class is essentially a class with a random name and 
some inline construction sugar, but apart from that does not differ from 
ordinary classes. (I've also seen some calls to allow syntax like $class = 
class {}; that would make that even more obvious.)

 

The situation here would be different if we had first-class classes and did not 
refer to classes by name. But as-is, I don't think garbage collecting anonymous 
classes is a possibility.

 

Nikita

 

> -----Original Message-----
> From: Stanislav Malyshev <smalys...@gmail.com <mailto:smalys...@gmail.com> >
> Sent: Saturday, June 29, 2019 6:52 AM
> To: Benjamin Morel <benjamin.mo...@gmail.com 
> <mailto:benjamin.mo...@gmail.com> >
> Cc: PHP Internals <internals@lists.php.net <mailto:internals@lists.php.net> >
> Subject: Re: [PHP-DEV] Memory leak in eval()'d code
> 
> 
> 
> On 6/28/19 3:37 PM, Benjamin Morel wrote:
> >     That's not a "leak". You create new objects (in this case, classes),
> >     they take memory.
> >
> >
> > Why do they not "leak" memory without eval() then? Replace with
> > `$object = new class {};` and memory usage stays flat.
> > There has do be some kind of garbage collection for these anonymous classes.
> 
> AFAIR this does not create new classes, since it's the same code, and same 
> code
> means same class. But eval() has new code every time, thus new class. 
> Generally
> I don't think PHP has any operation that can destroy an existing class. It 
> won't be
> easy too since you don't know whether there are any objects of this class
> around (unless you're in shutdown).
> 
> --
> Stas Malyshev
> smalys...@gmail.com <mailto:smalys...@gmail.com> 
> 
> --
> PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit:
> http://www.php.net/unsub.php
> 




-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to