php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66091 Memory leak in DateTime::createFromFormat()
Submitted: 2013-11-13 17:01 UTC Modified: 2014-04-06 13:00 UTC
Votes:7
Avg. Score:4.4 ± 0.9
Reproduced:7 of 7 (100.0%)
Same Version:6 (85.7%)
Same OS:7 (100.0%)
From: lars_teuber at gmx dot de Assigned: ab (profile)
Status: Closed Package: Unknown/Other Function
PHP Version: Irrelevant OS: Windows/Linux
Private report: No CVE-ID: None
 [2013-11-13 17:01 UTC] lars_teuber at gmx dot de
Description:
------------
Hi,

DateTime::createFromFormat() has a memory leak.

Tested with: 5.3.14, 5.4.4, 5.5.3

Best regards
Lars Teuber

Test script:
---------------
<?php
$mem_start = memory_get_usage(true);
echo 'start: ' . $mem_start . '<br>';

$max_iterations = 1000000;
for ($i = 1; $i <= $max_iterations; $i++) {
    DateTime::createFromFormat('M/D/Y H:i:s', '2013-11-12 20:00:00');
    if (($i % 100000) == 0) {
        echo $i . '.: ' . memory_get_usage(true) . '<br>';
    }
}
$mem_end = memory_get_usage(true);
echo 'end: ' . $mem_end . '<br>';
echo 'diff end-start: ' . ($mem_end - $mem_start) . '<br>';
?>

Expected result:
----------------
(more or less) constant memory usage

Actual result:
--------------
start:             524288
100000.:         16777216
200000.:         33030144
300000.:         53477376
400000.:         65536000
500000.:         77594624
600000.:        106168320
700000.:        118226944
800000.:        130285568
900000.:        142344192
1000000.:       154140672
end:            154140672
diff end-start: 153616384

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-04-05 17:03 UTC] ab@php.net
But in your code, you just continuously create new objects. It is then logic that the memory is cluttered up. Try using the return value and then explicitly unset() it.
 [2014-04-05 17:03 UTC] ab@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: ab
 [2014-04-05 17:03 UTC] ab@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

so marking as nab
 [2014-04-05 19:53 UTC] nikic@php.net
@ab: If you don't use the return value of a function call, it will be immidiately destroyed. As such there should be no difference between ignoring the return value and doing an assing+unset. To me this looks like we're indeed leaking something.
 [2014-04-06 13:00 UTC] ab@php.net
-Status: Not a bug +Status: Assigned
 [2014-04-06 13:00 UTC] ab@php.net
@nikic, now looking at the code of date_load_from_format i think you're right. In case it has to RETURN_FALSE a leak is possible. I will check that, thanks.
 [2014-07-18 04:31 UTC] nurlan0000 at gmail dot com
@ab, It's been almost a year since the bug was reported. Any updates on this?
 [2014-07-18 05:07 UTC] nurlan0000 at gmail dot com
Here's the valgrind output for test.php:

for ( $i = 0; $i < 100000; $i++ ) {
    $d = DateTime::createFromFormat('m-d-Y', '05-21-2014');
    unset($d);
}

valgrind --leak-check=yes --leak-check=full --show-leak-kinds=all php test.php


==21278== 5,922 bytes in 416 blocks are still reachable in loss record 14 of 18
==21278==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21278==    by 0x698C679: strdup (strdup.c:42)
==21278==    by 0x48BCB4: ??? (in /usr/bin/php5)
==21278==    by 0x48C164: timelib_builtin_db (in /usr/bin/php5)
==21278==    by 0x46D1CC: php_date_initialize (in /usr/bin/php5)
==21278==    by 0x46D41D: zif_date_create_from_format (in /usr/bin/php5)
==21278==    by 0x6DD6BA: dtrace_execute_internal (in /usr/bin/php5)
==21278==    by 0x79D714: ??? (in /usr/bin/php5)
==21278==    by 0x717447: execute_ex (in /usr/bin/php5)
==21278==    by 0x6DD5B8: dtrace_execute_ex (in /usr/bin/php5)
==21278==    by 0x6EF03F: zend_execute_scripts (in /usr/bin/php5)
==21278==    by 0x68EF24: php_execute_script (in /usr/bin/php5)
==21278== 
==21278== 8,168 bytes in 1 blocks are still reachable in loss record 15 of 18
==21278==    at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21278==    by 0x48BB48: ??? (in /usr/bin/php5)
==21278==    by 0x48C164: timelib_builtin_db (in /usr/bin/php5)
==21278==    by 0x46D1CC: php_date_initialize (in /usr/bin/php5)
==21278==    by 0x46D41D: zif_date_create_from_format (in /usr/bin/php5)
==21278==    by 0x6DD6BA: dtrace_execute_internal (in /usr/bin/php5)
==21278==    by 0x79D714: ??? (in /usr/bin/php5)
==21278==    by 0x717447: execute_ex (in /usr/bin/php5)
==21278==    by 0x6DD5B8: dtrace_execute_ex (in /usr/bin/php5)
==21278==    by 0x6EF03F: zend_execute_scripts (in /usr/bin/php5)
==21278==    by 0x68EF24: php_execute_script (in /usr/bin/php5)
==21278==    by 0x79F6ED: ??? (in /usr/bin/php5)
==21278== 
==21278== 9,029 bytes in 594 blocks are still reachable in loss record 16 of 18
==21278==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21278==    by 0x698C679: strdup (strdup.c:42)
==21278==    by 0x48B994: ??? (in /usr/bin/php5)
==21278==    by 0x48C15F: timelib_builtin_db (in /usr/bin/php5)
==21278==    by 0x46D1CC: php_date_initialize (in /usr/bin/php5)
==21278==    by 0x46D41D: zif_date_create_from_format (in /usr/bin/php5)
==21278==    by 0x6DD6BA: dtrace_execute_internal (in /usr/bin/php5)
==21278==    by 0x79D714: ??? (in /usr/bin/php5)
==21278==    by 0x717447: execute_ex (in /usr/bin/php5)
==21278==    by 0x6DD5B8: dtrace_execute_ex (in /usr/bin/php5)
==21278==    by 0x6EF03F: zend_execute_scripts (in /usr/bin/php5)
==21278==    by 0x68EF24: php_execute_script (in /usr/bin/php5)
==21278== 
==21278== 16,384 bytes in 1 blocks are still reachable in loss record 17 of 18
==21278==    at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21278==    by 0x48BA89: ??? (in /usr/bin/php5)
==21278==    by 0x48C15F: timelib_builtin_db (in /usr/bin/php5)
==21278==    by 0x46D1CC: php_date_initialize (in /usr/bin/php5)
==21278==    by 0x46D41D: zif_date_create_from_format (in /usr/bin/php5)
==21278==    by 0x6DD6BA: dtrace_execute_internal (in /usr/bin/php5)
==21278==    by 0x79D714: ??? (in /usr/bin/php5)
==21278==    by 0x717447: execute_ex (in /usr/bin/php5)
==21278==    by 0x6DD5B8: dtrace_execute_ex (in /usr/bin/php5)
==21278==    by 0x6EF03F: zend_execute_scripts (in /usr/bin/php5)
==21278==    by 0x68EF24: php_execute_script (in /usr/bin/php5)
==21278==    by 0x79F6ED: ??? (in /usr/bin/php5)
==21278== 
==21278== 43,264 bytes in 416 blocks are still reachable in loss record 18 of 18
==21278==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21278==    by 0x48BC85: ??? (in /usr/bin/php5)
==21278==    by 0x48C164: timelib_builtin_db (in /usr/bin/php5)
==21278==    by 0x46D1CC: php_date_initialize (in /usr/bin/php5)
==21278==    by 0x46D41D: zif_date_create_from_format (in /usr/bin/php5)
==21278==    by 0x6DD6BA: dtrace_execute_internal (in /usr/bin/php5)
==21278==    by 0x79D714: ??? (in /usr/bin/php5)
==21278==    by 0x717447: execute_ex (in /usr/bin/php5)
==21278==    by 0x6DD5B8: dtrace_execute_ex (in /usr/bin/php5)
==21278==    by 0x6EF03F: zend_execute_scripts (in /usr/bin/php5)
==21278==    by 0x68EF24: php_execute_script (in /usr/bin/php5)
==21278==    by 0x79F6ED: ??? (in /usr/bin/php5)
 [2014-07-18 05:25 UTC] nurlan0000 at gmail dot com
I think I've found situation when the memory leak occurs. 
Memory is leaked only when you try to parse invalid date.
Here's example script:

for ( $i = 0; $i < 10000; $i++ ) {
    $d = DateTime::createFromFormat('m-d-Y', 'asdf asdf');
    unset($d);
    
    if ($i % 100 == 0) {
        echo 'Memory usage: ', memory_get_usage(), PHP_EOL;
    }
}
 [2014-08-09 14:36 UTC] nurlan0000 at gmail dot com
[PATCH] I've submitted a patch here - https://github.com/php/php-src/pull/766
 [2014-08-13 12:28 UTC] datibbaw@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f6896e4395e89ceeacd8f8a940cbafeeee3ac4a3
Log: Fixed #66091
 [2014-08-13 12:28 UTC] datibbaw@php.net
-Status: Assigned +Status: Closed
 [2014-08-13 12:28 UTC] datibbaw@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4b85f1d46ad90ba8b31e4f961bd84c3e6fa0f0bf
Log: Fixed #66091
 [2014-08-14 00:52 UTC] tyrael@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f6896e4395e89ceeacd8f8a940cbafeeee3ac4a3
Log: Fixed #66091
 [2014-08-14 15:34 UTC] johannes@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f6896e4395e89ceeacd8f8a940cbafeeee3ac4a3
Log: Fixed #66091
 [2014-08-14 15:34 UTC] johannes@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4b85f1d46ad90ba8b31e4f961bd84c3e6fa0f0bf
Log: Fixed #66091
 [2014-08-14 19:32 UTC] dmitry@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4b85f1d46ad90ba8b31e4f961bd84c3e6fa0f0bf
Log: Fixed #66091
 [2014-08-14 19:32 UTC] dmitry@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f6896e4395e89ceeacd8f8a940cbafeeee3ac4a3
Log: Fixed #66091
 [2014-10-07 23:13 UTC] stas@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=f6896e4395e89ceeacd8f8a940cbafeeee3ac4a3
Log: Fixed #66091
 [2014-10-07 23:24 UTC] stas@php.net
Automatic comment on behalf of datibbaw
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=f6896e4395e89ceeacd8f8a940cbafeeee3ac4a3
Log: Fixed #66091
 [2022-07-27 06:17 UTC] rickychopra953 at gmail dot com
A touchless visitor management system is a safer way to handle the visitor sign-in process. It has some great features such as QR code and facial recognition which help in making your premises hygienic and capable to deter any infection.  


www.getveris.com/covid-visitor-screening-system
 [2024-03-16 02:04 UTC] jasminemercer1 at outlook dot com
0

Very unlikely a memory leak causes by a DateTime object. Generally, if an object is not Disposable and doesn't have event subscriptions (to a long lasting instance) it shouldn't be the root cause for a memory leak. Having said that you really need a proper tool (eg: RedGate Memory Profiler) to analyze memory leaks.

The code you have provided is not enough to say anything about the memory leak. However, keep in mind you MUST dispose all Disposable objects when you don't need them any more. Use 'using' when you are creating a local disposable object, it will dispose the instance when it is going out of the scope. Specially when you are using any kind of streams it is the best practice to wrap them within a using clause. It will close it and dispose for you(dispose actually closes the stream when disposing).

So, yes. Try disposing all disposable objects and test again. 'backData' object looks suspicious to me. Make sure you clear or dispose it appropriately.

https://ncedcloudam.com.github.com
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 17:01:29 2024 UTC