Edit report at https://bugs.php.net/bug.php?id=70098&edit=1
ID: 70098
User updated by: robin dot kunde at recoursive dot com
Reported by: robin dot kunde at recoursive dot com
Summary: Real memory usage doesn't decrease
Status: Assigned
Type: Bug
Package: Performance problem
Operating System: Ubuntu 15.04, OSX 10.10.4
PHP Version: 7.0.0beta1
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
Base on what you said, I performed another test:
I set memory_limit to 512M. At the end of the script I posted, after nulling out all the vars, and
memory usage being (Real: 422.00, Malloc: 0.36), I tried to read a 200M file. This triggered the
memory exhaustion fatal error. If I read the large file at the beginning of the script, and then
null the var, the script runs as expected and memory usage doesn't change much since it's
a large allocation.
I'm glad that the small bucket pool is counted against the memory limit and scripts can't
accidentally use up to twice as much memory. However, it does make the behavior of long running,
memory intensive script potentially unpredictable.
I understand the performance implications of not having to free those buckets. As a compromise, the
small bucket pool could be cleaned only when absolutely necessary.
Previous Comments:
------------------------------------------------------------------------
[2015-07-20 13:17:25] laruence@php.net
actually , it won't , let's say you have allocated a 7bytes memory , then one page of 4KB
will allocated for it. and unless there is no any 8 bytes slot in this page, any request for
allocating < 8 bytes won't trigger new memory allocating request to OS...
anyway, maybe we should add some gc of memory if mmap fails of OOM...
------------------------------------------------------------------------
[2015-07-20 11:47:24] bwoebi@php.net
The memory is never released back to the system. That may go bad with a few long running worker
processes doing complicated calculations with a lot of data.
They'll eat all the memory and system will need to swap (or slow down in other waysâ¦).
Hence I think we should care.
------------------------------------------------------------------------
[2015-07-20 06:12:36] laruence@php.net
why we need them ? this is just a particular case that triggers allocates lot's of size type..
and it won't affacts memory_get_usage(false)...
------------------------------------------------------------------------
[2015-07-19 17:45:07] bwoebi@php.net
PHP 7 uses a new memory allocator, which puts small allocations of 3 KB or less into buckets with
well defined sizes. These small buckets though⦠are never freed.
@Dmitry: Is that intentional that they're never freed? I see no handling logic for unmmapping
these... Sure, it's faster to not have logic which frees them, but seems we need it.
------------------------------------------------------------------------
[2015-07-18 20:43:38] robin dot kunde at recoursive dot com
Description:
------------
PHP 7b1 doesn't appear to be reclaiming freed memory correctly. This problem only affects real
usage as reported by memory_get_usage(true). Usage as reported by memory_get_usage(false) behaves as
expected.
The problem appears to be related to allocation of strings, the use of stdclass, and/or
multidimensional array. I don't believe PHP is actually leaking memory, since usage is not
continuously increasing. It just appear that certain actions prevent real usage from decreasing
again after variables are nulled out or leave scope. The test script gist I posted can demonstrates
the problem better than I can explain it.
This problem still occurs with the master git branch as of 7/17.
Test script:
---------------
https://gist.github.com/robinkunde/68f3d442aa294550ab15
Expected result:
----------------
PHP 5.6.11
Assembling 5M string
Real: 0.50, Malloc: 0.25
Storing 1M bools
Real: 0.75, Malloc: 0.25
Real: 1.00, Malloc: 0.25
Real: 1.00, Malloc: 0.25
Storing 1M ints
Real: 1.25, Malloc: 0.25
Real: 1.25, Malloc: 0.25
Real: 1.50, Malloc: 0.25
Storing 1M stringyfied ints
Real: 1.50, Malloc: 0.25
Real: 1.75, Malloc: 0.25
Real: 1.75, Malloc: 0.25
Storing 1M stringyfied ints with stringyfied int keys
Real: 1.75, Malloc: 0.25
Real: 1.75, Malloc: 0.25
Real: 1.75, Malloc: 0.25
Storing 1M empty strings
Real: 1.75, Malloc: 0.25
Real: 2.00, Malloc: 0.25
Real: 2.00, Malloc: 0.25
Storing 1M hellos
Real: 2.00, Malloc: 0.25
Real: 2.25, Malloc: 0.25
Real: 2.00, Malloc: 0.25
Storing 1M hellos with stringyfied int keys
Real: 2.00, Malloc: 0.25
Storing 1M empty arrays
Real: 1.50, Malloc: 0.25
Real: 2.00, Malloc: 0.25
Real: 2.00, Malloc: 0.25
Storing 1M arrays with empty strings
Real: 2.00, Malloc: 0.25
Real: 2.50, Malloc: 0.25
Real: 2.50, Malloc: 0.25
Storing 1M arrays with hello
Real: 2.50, Malloc: 0.25
Real: 2.75, Malloc: 0.25
Real: 2.75, Malloc: 0.25
Final Usage
Real: 2.75, Malloc: 0.25
Real peak: 436.00, Malloc peak: 435.50
Actual result:
--------------
PHP 7.0.0b1
Assembling 5M string
Real: 4.00, Malloc: 0.36
Storing 1M bools
Real: 4.00, Malloc: 0.36
Real: 32.00, Malloc: 0.36
Real: 32.00, Malloc: 0.36
Storing 1M ints
Real: 32.00, Malloc: 0.36
Real: 32.00, Malloc: 0.36
Real: 32.00, Malloc: 0.36
Storing 1M stringyfied ints
Real: 32.00, Malloc: 0.36
Real: 62.00, Malloc: 0.36
Real: 62.00, Malloc: 0.36
Storing 1M stringyfied ints with stringyfied int keys
Real: 62.00, Malloc: 0.36
Real: 62.00, Malloc: 0.36
Real: 62.00, Malloc: 0.36
Storing 1M empty strings
Real: 62.00, Malloc: 0.36
Real: 62.00, Malloc: 0.36
Real: 62.00, Malloc: 0.36
Storing 1M hellos
Real: 62.00, Malloc: 0.36
Real: 62.00, Malloc: 0.36
Real: 62.00, Malloc: 0.36
Storing 1M hellos with stringyfied int keys
Real: 62.00, Malloc: 0.36
Storing 1M empty arrays
Real: 116.00, Malloc: 0.36
Real: 116.00, Malloc: 0.36
Real: 116.00, Malloc: 0.36
Storing 1M arrays with empty strings
Real: 422.00, Malloc: 0.36
Real: 422.00, Malloc: 0.36
Real: 422.00, Malloc: 0.36
Storing 1M arrays with hello
Real: 422.00, Malloc: 0.36
Real: 422.00, Malloc: 0.36
Real: 422.00, Malloc: 0.36
Final Usage
Real: 422.00, Malloc: 0.36
Real peak: 476.00, Malloc peak: 425.46
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=70098&edit=1