Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:106108 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 80427 invoked from network); 29 Jun 2019 18:13:56 -0000 Received: from unknown (HELO smtpproxy19.qq.com) (184.105.206.84) by pb1.pair.com with SMTP; 29 Jun 2019 18:13:56 -0000 X-QQ-mid:Yeas8t1561822259t592t12838 Received: from 14D73359B2E14ADDB4DDC3857AE32898 (me@jhdxr.com [220.255.44.152]) X-QQ-SSF:00000000000000F0F61000000000000 To: "'Nikita Popov'" Cc: "'Stanislav Malyshev'" , "'Benjamin Morel'" , "'PHP Internals'" References: <8f07c0dc-f9a5-8c76-1d48-0fac762bfc4f@gmail.com> <92dba455-17df-41dd-c523-bb0db3c12078@gmail.com> <003b01d52e49$4db89390$e929bab0$@jhdxr.com> In-Reply-To: Date: Sat, 29 Jun 2019 23:30:50 +0800 Message-ID: <000001d52e8f$a1f92b40$e5eb81c0$@jhdxr.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0001_01D52ED2.B01D7CB0" X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQGNUWw+475Jgca4R2IsmDo72cP1JgLEeVtGApLIHtEBYAxcbACSYCsTAiPDS8MApMvubqbx1pgw Content-Language: zh-cn X-QQ-SENDSIZE: 520 Feedback-ID: Yeas:jhdxr.com:qybgforeign:qybgforeign2 X-QQ-Bgrelay: 1 Subject: RE: [PHP-DEV] Memory leak in eval()'d code From: me@jhdxr.com (=?utf-8?b?Q0hVIFpoYW93ZWk=?=) ------=_NextPart_000_0001_01D52ED2.B01D7CB0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Thanks for the example. Now I understand the root cause. There is a = similar bug report(https://bugs.php.net/bug.php?id=3D74938) for = anonymous function. I thought it leaked for the same reason, but now I = think I=E2=80=99m wrong. We don=E2=80=99t have to create new classes for = them since they are all instances of Closure class, and it=E2=80=99s not = possible to create opaque reference for functions. __FUNCTION__ returns = =E2=80=9C{closure}=E2=80=9D. Could you take a look? =20 Back to the anonymous class, I=E2=80=99m 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=E2=80=99s safe to remove the class definition during = destruction. =20 Regards, CHU Zhaowei =20 From: Nikita Popov =20 Sent: Saturday, June 29, 2019 3:58 PM To: CHU Zhaowei Cc: Stanislav Malyshev ; Benjamin Morel = ; PHP Internals Subject: Re: [PHP-DEV] Memory leak in eval()'d code =20 On Sat, Jun 29, 2019 at 9:07 AM CHU Zhaowei > 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.=20 I guess the problem here is we didn't GC the space for definition of = anonymous classes. Regards, CHU Zhaowei =20 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: =20 $obj =3D eval('return new class {}'); $class =3D get_class($obj); // create opaque reference unset($obj); // drop last direct reference $obj =3D new $class; =20 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 =3D class {}; that would make that even more obvious.) =20 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. =20 Nikita =20 > -----Original Message----- > From: Stanislav Malyshev > > Sent: Saturday, June 29, 2019 6:52 AM > To: Benjamin Morel > > Cc: PHP Internals > > Subject: Re: [PHP-DEV] Memory leak in eval()'d code >=20 >=20 >=20 > 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 =3D new class {};` and memory usage stays flat. > > There has do be some kind of garbage collection for these anonymous = classes. >=20 > 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). >=20 > -- > Stas Malyshev > smalyshev@gmail.com =20 >=20 > -- > PHP Internals - PHP Runtime Development Mailing List To unsubscribe, = visit: > http://www.php.net/unsub.php >=20 --=20 PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php ------=_NextPart_000_0001_01D52ED2.B01D7CB0--