Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:106111 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 91679 invoked from network); 29 Jun 2019 19:03:49 -0000 Received: from unknown (HELO mail-lf1-f52.google.com) (209.85.167.52) by pb1.pair.com with SMTP; 29 Jun 2019 19:03:49 -0000 Received: by mail-lf1-f52.google.com with SMTP id y17so6006143lfe.0 for ; Sat, 29 Jun 2019 09:21:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=RkAiq3RpBcX+1ZaXgDuwIDblULvjBjbOXGvOIhajMCM=; b=kmy1MyCU11RjZbYJuHp0k6+HZBWzKlZHXm/xRyJKf4r/dVJvdkvl2i+o+1Gw5lOmIL niKy8BL47G43h8/pAFcE1Tct12DIDOMMKMtBNe0CSN8DRfFVHrW7wCPQWUSms2f+40kJ yz2y7u2LooeQeLEyBndCsw/1VQY5RY1icFn0ErxVo73sHkbRxxkqtMFy/sLrtl8y6zPo 9c1hPT9llX7Bxfs1tKrzK0YXYWqm1rBwkkOMplgizyoyEtmS4wEKzYE3gNoZsQeVAaI4 XqFNsE25S4FIijuITXzDIcHfJnKMp6JQD9EpCwiD9WBtYwHQqbyQd+ySrTU5RzMf9zsW BAQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=RkAiq3RpBcX+1ZaXgDuwIDblULvjBjbOXGvOIhajMCM=; b=NE1jyVIllIFI0LAtf4iC996E7xIAU97GME9tMnExWF9z+LDj+HSJNMXYOsV9vA0yfG Y0VgnFvOUOFJugQAW9QELzb8V6b6FOuYfXhgu1FsuosxOsGDezb8RAlapp9EjyPTJQHH 8E6ybpW8UsxFQ2Hcwl+yHIRUtYAk3VBidzgCbw/j0xTpHiMZJLcXPmIxztqgDAlrWya1 iowLfynhMzN5P0/3yUY5v+4FSFkoBC9c/bbfv5+EwBZMgB2u0on8ZKENmO0Bw1FC+kGX 0wCb8BYHuHDR++qBH5Z6Lhd+/wljy7RP+Sa65aqd9Eh5O0nd7aLM0EMxaTjNZlDf/N3I f2ig== X-Gm-Message-State: APjAAAV+5N1MLmv5dmsWv6BpcfqbzClXFS7zfLiPH+rbUnIpXbm3gPbe RG5e4bNzml7Ewysqnv5XmwkerE4fw/eaYLQXP/A= X-Google-Smtp-Source: APXvYqxFmlHg97mJSgdo547vMbYMKJ/OPJNebnVw9lBXqGez8TumQ1Wst2vPUc3WV1j99IBmie700aA9xku1cfKMJ2M= X-Received: by 2002:a19:4017:: with SMTP id n23mr8298763lfa.112.1561825259366; Sat, 29 Jun 2019 09:20:59 -0700 (PDT) MIME-Version: 1.0 References: <8f07c0dc-f9a5-8c76-1d48-0fac762bfc4f@gmail.com> <92dba455-17df-41dd-c523-bb0db3c12078@gmail.com> <003b01d52e49$4db89390$e929bab0$@jhdxr.com> <000001d52e8f$a1f92b40$e5eb81c0$@jhdxr.com> In-Reply-To: <000001d52e8f$a1f92b40$e5eb81c0$@jhdxr.com> Date: Sat, 29 Jun 2019 18:20:43 +0200 Message-ID: To: CHU Zhaowei Cc: Stanislav Malyshev , Benjamin Morel , PHP Internals Content-Type: multipart/alternative; boundary="000000000000c92e80058c78c793" Subject: Re: [PHP-DEV] Memory leak in eval()'d code From: nikita.ppv@gmail.com (Nikita Popov) --000000000000c92e80058c78c793 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, Jun 29, 2019 at 5:31 PM CHU Zhaowei wrote: > 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 ar= e all > instances of Closure class, and it=E2=80=99s not possible to create opaqu= e > reference for functions. __FUNCTION__ returns =E2=80=9C{closure}=E2=80= =9D. Could you take > a look? > This leaks for the same reason (function definition is not garbage collected), but in this case we could indeed implement the garbage collection without any observable changes to semantics. I don't think it will be simple to do this though. Back to the anonymous class, I=E2=80=99m thinking if we can have any worka= round > 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 clas= s > at all. > I think you got caught up in a wrong premise here: Just using anonymous classes does not cause leaks. The problem here is that OP is *creating* many classes (the fact that they are anonymous ultimately doesn't matter) by eval'ing code. That is what causes the leak. Unless you are doing something like this (which you obviously shouldn't, for more reasons than this), there is nothing to worry about. As such, I don't really think there is a problem worth solving here. Nikita 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? Wit= h > the help of this flag, we are able to know if it=E2=80=99s safe to remove= the class > definition during destruction. > Regards, > > CHU Zhaowei > > > > *From:* Nikita Popov > *Sent:* Saturday, June 29, 2019 3:58 PM > *To:* CHU Zhaowei > *Cc:* Stanislav Malyshev ; Benjamin Morel < > benjamin.morel@gmail.com>; PHP Internals > *Subject:* Re: [PHP-DEV] Memory leak in eval()'d code > > > > 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. > 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 clas= s > definitions due to the existence of opaque references. A simple example o= f > code that currently works: > > > > $obj =3D eval('return new class {}'); > > $class =3D get_class($obj); // create opaque reference > > unset($obj); // drop last direct reference > > $obj =3D 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 =3D 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 > > Sent: Saturday, June 29, 2019 6:52 AM > > To: Benjamin Morel > > Cc: PHP Internals > > 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 =3D 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 cla= ss > > around (unless you're in shutdown). > > > > -- > > Stas Malyshev > > smalyshev@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 > > --000000000000c92e80058c78c793--