Bug #81251 [Com]: Memory leak with datetime, serialization, and require

From: Date: Mon, 26 Jun 2023 08:05:10 +0000
Subject: Bug #81251 [Com]: Memory leak with datetime, serialization, and require
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-244812@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81251&edit=1 ID: 81251 Comment by: gerefo6485 at aramask dot com Reported by: lyrixx at lyrixx dot info Summary: Memory leak with datetime, serialization, and require Status: Wont fix Type: Bug Package: Variables related Operating System: linux PHP Version: 8.0.8 Assigned To: cmb Block user comment: N Private report: N New Comment: Nice Article here good one. (https://www.librarygenesis.xyz)php.net Previous Comments: ------------------------------------------------------------------------ [2021-07-12 13:04:16] nikic@php.net This isn't the same issue as bug #81142. There the unserialize() implementation itself interns some strings. It shouldn't be going that, because the strings are potentially runtime-derived. Here you are creating PHP files with distinct string literals (there isn't any particular relation to unserialize -- you're just creating different strings through it, thanks to microseconds on DateTime). These should get interned, as they are compile-time constants strings as far as PHP is concerned. We will not change this behavior. The same happens with opcache, but the strings will be in shared memory, so it will be part of opcache's memory usage, not memory_get_usage(). ------------------------------------------------------------------------ [2021-07-12 12:52:22] lyrixx at lyrixx dot info Thanks for the comment. BTW, I noticed that : php test.php => Memory leak php -n test.php => Memory leak php -n -d zend_extension=opcache -d "opcache.enable_cli=on" test.php => NO memory leak ! This is a bit crazy to me. Anyway, I fail to see why the relation with bug #81142. There is **no array** in my case. More over, as I noticed in the initial bug report, if the code don't goes through "require", there is not memory leak. So "unserialize(serialize($foobar))" doesn't leak in my case. ------------------------------------------------------------------------ [2021-07-12 12:43:00] cmb@php.net This reproduces on PHP-7.4 as well, and is because the different serialized strings are all interned; see bug #81142. ------------------------------------------------------------------------ [2021-07-12 10:05:03] lyrixx at lyrixx dot info Description: ------------ When one require a PHP script, that unserialize some data with an instance of DateTime in it, a memory leak occurs Test script: --------------- <?php class Foobar { public function __construct( // If this property is removed => No leak public DateTime $d, ) { } } for ($i=0; $i < 10000; $i++) { $foobar = new Foobar(new \DateTime()); // 1. Leak when "require" is involved $file = '/tmp/test-serialized.php'; file_put_contents($file, sprintf("<?php return unserialize(base64_decode('%s'));\n", base64_encode(serialize($foobar)))); $o = require $file; // 2. No leak in this case // unserialize(serialize($foobar)); if ($i % 1000 === 0) { printf("%.2fMb\n", memory_get_usage() / 1024 / 1024); } } Expected result: ---------------- 0.38Mb 0.38Mb 0.38Mb 0.38Mb 0.38Mb 0.38Mb 0.38Mb 0.38Mb 0.38Mb 0.38Mb Actual result: -------------- 0.38Mb 0.66Mb 0.90Mb 1.23Mb 1.47Mb 1.87Mb 2.11Mb 2.36Mb 2.60Mb 3.16Mb ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=81251&edit=1

« previous php.bugs (#244812) next »