Closed degtyaryov closed 8 years ago
Maybe related to #497 @krakjoe said "Don't use anything not designed for multi-threading."
There is no bug here.
PHP and C manage memory differently.
I thought that the problem is pthread_join, but example C gave me to understand that is not the point.
If sleep is replaced by any code then problem is so exists:
<?php
class ThreadTest extends Thread {
public function run() {
for ($i = 0; $i < 2500000; $i++) {
}
}
public function __destruct() {
echo '#';
}
}
$threads_count = 1000;
$threads = [];
for ($i = 0; $i < $threads_count; $i++) {
$thread = new ThreadTest();
if (!$thread->start()) {
die('ERROR, so far '.$i.' threads created'."\n");
}
$threads[] = $thread;
}
foreach ($threads as $i => $thread) {
if (!$thread->join()) {
echo 'ERROR, joined with thread ',$i,"\n";
}
}
unset($i, $threads, $thread, $threads_count);
while (true) {
echo '.';
sleep(1);
}
?>
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3912 test 20 0 2590204 379308 10768 S 0,0 6,3 4:01.45 zts-php test.php
Why process using 400Mb memory?
@degtyaryov On Windows 10 x64 it just crash, 2 Gb RAM used and Windows say "CLI stopped working"
My OS Fedora 23, RAM 6 Gb.
Change thread count for test on machine 2Gb RAM:
$threads_count = 500;
or more less
$threads_count = 300;
In moment working while(true) { sleep(1); } memory must be released. Why 400 Mb?
Test this function http://php.net/manual/fr/function.gc-collect-cycles.php on your while
gc_enable and gc_collect_cycles not solve the problem.
I change test to:
<?php
echo 'run: ', date('Y-m-d H:i:s'), ' - memory_get_usage(): ', memory_get_usage(), ', memory_get_usage(true): ', memory_get_usage(true), "\n";
gc_enable();
class ThreadTest extends Thread {
public function run() {
gc_enable();
//for ($i = 0; $i < 2500000; $i++) {} // For PHP5, pthreads-2.0.11, Fedora 19, CPU 4 Cores, RAM 6GB
for ($i = 0; $i < 30000000; $i++) {} // For PHP7, pthreads-3.1.3, Fedora 23, CPU 8 Cores, RAM 8GB
gc_collect_cycles();
}
}
$threads_count = 1000;
$threads = [];
for ($i = 0; $i < $threads_count; $i++) {
$thread = new ThreadTest();
if (!$thread->start()) {
die('ERROR, so far '.$i.' threads created'."\n");
}
$threads[] = $thread;
}
foreach ($threads as $i => $thread) {
if (!$thread->join()) {
echo 'ERROR, joined with thread ',$i,"\n";
}
}
echo 'before unset: ', date('Y-m-d H:i:s'), ' - memory_get_usage(): ', memory_get_usage(), ', memory_get_usage(true): ', memory_get_usage(true), "\n";
gc_collect_cycles();
unset($i, $threads, $thread, $threads_count);
gc_collect_cycles();
echo 'after unset: ', date('Y-m-d H:i:s'), ' - memory_get_usage(): ', memory_get_usage(), ', memory_get_usage(true): ', memory_get_usage(true), "\n";
while (true) {
echo 'in while loop: ', date('Y-m-d H:i:s'), ' - memory_get_usage(): ', memory_get_usage(), ', memory_get_usage(true): ', memory_get_usage(true), "\n";
sleep(1);
gc_collect_cycles();
}
For PHP7, pthreads-3.1.3, Fedora 23, CPU 8 Cores, RAM 8GB:
$ zts-php ./test.php
run: 2015-11-26 14:20:18 - memory_get_usage(): 360712, memory_get_usage(true): 2097152
before unset: 2015-11-26 14:21:25 - memory_get_usage(): 526080, memory_get_usage(true): 2097152
after unset: 2015-11-26 14:21:25 - memory_get_usage(): 361160, memory_get_usage(true): 2097152
in while loop: 2015-11-26 14:21:25 - memory_get_usage(): 361160, memory_get_usage(true): 2097152
in while loop: 2015-11-26 14:21:26 - memory_get_usage(): 361160, memory_get_usage(true): 2097152
in while loop: 2015-11-26 14:21:27 - memory_get_usage(): 361160, memory_get_usage(true): 2097152
......
in while loop: 2015-11-26 14:46:32 - memory_get_usage(): 361160, memory_get_usage(true): 2097152
in while loop: 2015-11-26 14:46:33 - memory_get_usage(): 361160, memory_get_usage(true): 2097152
in while loop: 2015-11-26 14:46:34 - memory_get_usage(): 361160, memory_get_usage(true): 2097152
in while loop: 2015-11-26 14:46:35 - memory_get_usage(): 361160, memory_get_usage(true): 2097152
Memory usage from ps command:
$ while true; do date -u --rfc-3339=seconds | tr '\n' ' ' && ps aux | grep 'test.php' | grep -v grep | awk '{print "VIRT: "$5", RES: "$6}'; sleep 1; done
2015-11-26 14:20:19+00:00 VIRT: 4328252, RES: 30824
2015-11-26 14:20:20+00:00 VIRT: 5343092, RES: 39792
2015-11-26 14:20:21+00:00 VIRT: 5619700, RES: 46712
2015-11-26 14:20:22+00:00 VIRT: 5817076, RES: 52288
2015-11-26 14:20:23+00:00 VIRT: 5949460, RES: 57572
2015-11-26 14:20:24+00:00 VIRT: 6097604, RES: 63948
2015-11-26 14:20:25+00:00 VIRT: 6210288, RES: 67052
2015-11-26 14:20:26+00:00 VIRT: 6332428, RES: 69268
2015-11-26 14:20:27+00:00 VIRT: 6449056, RES: 74132
2015-11-26 14:20:28+00:00 VIRT: 6564892, RES: 76960
2015-11-26 14:20:29+00:00 VIRT: 6688608, RES: 81216
2015-11-26 14:20:30+00:00 VIRT: 6801764, RES: 88200
2015-11-26 14:20:31+00:00 VIRT: 6913712, RES: 91640
2015-11-26 14:20:32+00:00 VIRT: 7034604, RES: 94468
2015-11-26 14:20:33+00:00 VIRT: 7178032, RES: 97028
2015-11-26 14:20:34+00:00 VIRT: 7309168, RES: 98732
2015-11-26 14:20:35+00:00 VIRT: 7420140, RES: 99916
2015-11-26 14:20:36+00:00 VIRT: 7551272, RES: 101516
2015-11-26 14:20:37+00:00 VIRT: 7676264, RES: 102428
2015-11-26 14:20:38+00:00 VIRT: 7813544, RES: 103748
2015-11-26 14:20:40+00:00 VIRT: 7928292, RES: 106564
2015-11-26 14:20:41+00:00 VIRT: 8063524, RES: 107648
2015-11-26 14:20:42+00:00 VIRT: 8178272, RES: 108560
2015-11-26 14:20:43+00:00 VIRT: 8325796, RES: 109448
2015-11-26 14:20:44+00:00 VIRT: 8442592, RES: 110332
2015-11-26 14:20:45+00:00 VIRT: 8606508, RES: 111276
2015-11-26 14:20:46+00:00 VIRT: 8772472, RES: 111948
2015-11-26 14:20:47+00:00 VIRT: 8883120, RES: 112836
2015-11-26 14:20:48+00:00 VIRT: 9036792, RES: 113040
2015-11-26 14:20:49+00:00 VIRT: 9165876, RES: 114120
2015-11-26 14:20:50+00:00 VIRT: 9301108, RES: 114468
2015-11-26 14:20:51+00:00 VIRT: 9409708, RES: 114868
2015-11-26 14:20:52+00:00 VIRT: 9524452, RES: 115412
2015-11-26 14:20:53+00:00 VIRT: 9612560, RES: 115936
2015-11-26 14:20:54+00:00 VIRT: 9725260, RES: 116764
2015-11-26 14:20:55+00:00 VIRT: 9840008, RES: 116992
2015-11-26 14:20:56+00:00 VIRT: 9971144, RES: 117448
2015-11-26 14:20:57+00:00 VIRT: 10120720, RES: 117860
2015-11-26 14:20:58+00:00 VIRT: 10253908, RES: 118456
2015-11-26 14:20:59+00:00 VIRT: 10378896, RES: 118672
2015-11-26 14:21:00+00:00 VIRT: 10491596, RES: 119176
2015-11-26 14:21:01+00:00 VIRT: 10655508, RES: 119256
2015-11-26 14:21:02+00:00 VIRT: 10798932, RES: 119600
2015-11-26 14:21:03+00:00 VIRT: 10915728, RES: 119744
2015-11-26 14:21:04+00:00 VIRT: 11032840, RES: 120184
2015-11-26 14:21:06+00:00 VIRT: 11174216, RES: 120376
2015-11-26 14:21:07+00:00 VIRT: 11270528, RES: 120884
2015-11-26 14:21:08+00:00 VIRT: 11391420, RES: 121076
2015-11-26 14:21:09+00:00 VIRT: 11516408, RES: 121472
2015-11-26 14:21:10+00:00 VIRT: 11643448, RES: 121684
2015-11-26 14:21:11+00:00 VIRT: 11807364, RES: 122284
2015-11-26 14:21:12+00:00 VIRT: 11915964, RES: 122828
2015-11-26 14:21:13+00:00 VIRT: 12036856, RES: 123384
2015-11-26 14:21:14+00:00 VIRT: 12200768, RES: 123500
2015-11-26 14:21:15+00:00 VIRT: 12309372, RES: 123944
2015-11-26 14:21:16+00:00 VIRT: 12456896, RES: 124048
2015-11-26 14:21:17+00:00 VIRT: 12585980, RES: 124520
2015-11-26 14:21:18+00:00 VIRT: 12698676, RES: 125024
2015-11-26 14:21:19+00:00 VIRT: 12821616, RES: 125540
2015-11-26 14:21:20+00:00 VIRT: 5883708, RES: 112068
2015-11-26 14:21:21+00:00 VIRT: 5701364, RES: 111968
2015-11-26 14:21:22+00:00 VIRT: 5475996, RES: 111904
2015-11-26 14:21:23+00:00 VIRT: 5260872, RES: 111736
2015-11-26 14:21:24+00:00 VIRT: 4826528, RES: 111428
2015-11-26 14:21:25+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:21:26+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:21:27+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:21:28+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:21:29+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:21:30+00:00 VIRT: 4451596, RES: 111116
......
2015-11-26 14:46:27+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:46:28+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:46:29+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:46:30+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:46:31+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:46:32+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:46:33+00:00 VIRT: 4451596, RES: 111116
2015-11-26 14:46:34+00:00 VIRT: 4451596, RES: 111116
For PHP5, pthreads-2.0.11, Fedora 19, CPU 4 Cores, RAM 6GB:
$ zts-php ./test.php
run: 2015-11-26 19:32:06 - memory_get_usage(): 251568, memory_get_usage(true): 262144
before unset: 2015-11-26 19:33:08 - memory_get_usage(): 396752, memory_get_usage(true): 524288
after unset: 2015-11-26 19:33:08 - memory_get_usage(): 251872, memory_get_usage(true): 524288
in while loop: 2015-11-26 19:33:08 - memory_get_usage(): 251872, memory_get_usage(true): 524288
in while loop: 2015-11-26 19:33:09 - memory_get_usage(): 251872, memory_get_usage(true): 524288
in while loop: 2015-11-26 19:33:10 - memory_get_usage(): 251872, memory_get_usage(true): 524288
in while loop: 2015-11-26 19:33:11 - memory_get_usage(): 251872, memory_get_usage(true): 524288
in while loop: 2015-11-26 19:33:12 - memory_get_usage(): 251872, memory_get_usage(true): 524288
.........
in while loop: 2015-11-26 19:54:02 - memory_get_usage(): 251872, memory_get_usage(true): 524288
in while loop: 2015-11-26 19:54:03 - memory_get_usage(): 251872, memory_get_usage(true): 524288
in while loop: 2015-11-26 19:54:04 - memory_get_usage(): 251872, memory_get_usage(true): 524288
Memory usage from ps command:
2015-11-26 14:32:07+00:00 VIRT: 2533564, RES: 78708
2015-11-26 14:32:08+00:00 VIRT: 2996164, RES: 142212
2015-11-26 14:32:09+00:00 VIRT: 3166640, RES: 173244
2015-11-26 14:32:10+00:00 VIRT: 3322496, RES: 191480
2015-11-26 14:32:11+00:00 VIRT: 3471372, RES: 210864
2015-11-26 14:32:12+00:00 VIRT: 3602064, RES: 221764
2015-11-26 14:32:13+00:00 VIRT: 3736788, RES: 229784
2015-11-26 14:32:14+00:00 VIRT: 3884316, RES: 237888
2015-11-26 14:32:15+00:00 VIRT: 4015452, RES: 242652
2015-11-26 14:32:16+00:00 VIRT: 4146720, RES: 249452
2015-11-26 14:32:17+00:00 VIRT: 4294248, RES: 261512
2015-11-26 14:32:18+00:00 VIRT: 4433580, RES: 266764
2015-11-26 14:32:19+00:00 VIRT: 4572912, RES: 267816
2015-11-26 14:32:20+00:00 VIRT: 4728636, RES: 271104
2015-11-26 14:32:21+00:00 VIRT: 4859772, RES: 278180
2015-11-26 14:32:22+00:00 VIRT: 4999236, RES: 280840
2015-11-26 14:32:23+00:00 VIRT: 5138568, RES: 284760
2015-11-26 14:32:24+00:00 VIRT: 5269704, RES: 285248
2015-11-26 14:32:25+00:00 VIRT: 5400840, RES: 286124
2015-11-26 14:32:26+00:00 VIRT: 5548368, RES: 286676
2015-11-26 14:32:27+00:00 VIRT: 5687832, RES: 289552
2015-11-26 14:32:28+00:00 VIRT: 5818968, RES: 290108
2015-11-26 14:32:30+00:00 VIRT: 5950104, RES: 290708
2015-11-26 14:32:31+00:00 VIRT: 6081240, RES: 291072
2015-11-26 14:32:32+00:00 VIRT: 6220572, RES: 293588
2015-11-26 14:32:33+00:00 VIRT: 6360036, RES: 293972
2015-11-26 14:32:34+00:00 VIRT: 6491172, RES: 294412
2015-11-26 14:32:35+00:00 VIRT: 6630504, RES: 295700
2015-11-26 14:32:36+00:00 VIRT: 6769836, RES: 299256
2015-11-26 14:32:37+00:00 VIRT: 6900972, RES: 303972
2015-11-26 14:32:38+00:00 VIRT: 7040436, RES: 306568
2015-11-26 14:32:39+00:00 VIRT: 7171572, RES: 307180
2015-11-26 14:32:40+00:00 VIRT: 7310904, RES: 309444
2015-11-26 14:32:41+00:00 VIRT: 7450236, RES: 310036
2015-11-26 14:32:42+00:00 VIRT: 7605960, RES: 310600
2015-11-26 14:32:43+00:00 VIRT: 7728900, RES: 313708
2015-11-26 14:32:44+00:00 VIRT: 7868364, RES: 316192
2015-11-26 14:32:45+00:00 VIRT: 8015892, RES: 316644
2015-11-26 14:32:46+00:00 VIRT: 8130636, RES: 319112
2015-11-26 14:32:47+00:00 VIRT: 8269968, RES: 319520
2015-11-26 14:32:48+00:00 VIRT: 8409300, RES: 319868
2015-11-26 14:32:49+00:00 VIRT: 8548632, RES: 323136
2015-11-26 14:32:50+00:00 VIRT: 8704356, RES: 323248
2015-11-26 14:32:51+00:00 VIRT: 8835492, RES: 330160
2015-11-26 14:32:52+00:00 VIRT: 8958432, RES: 330292
2015-11-26 14:32:53+00:00 VIRT: 9114156, RES: 330732
2015-11-26 14:32:54+00:00 VIRT: 9245292, RES: 337796
2015-11-26 14:32:55+00:00 VIRT: 9376428, RES: 346820
2015-11-26 14:32:56+00:00 VIRT: 9515760, RES: 349076
2015-11-26 14:32:57+00:00 VIRT: 9655092, RES: 354584
2015-11-26 14:32:58+00:00 VIRT: 9786228, RES: 354804
2015-11-26 14:32:59+00:00 VIRT: 9909168, RES: 358004
2015-11-26 14:33:00+00:00 VIRT: 10048500, RES: 359564
2015-11-26 14:33:01+00:00 VIRT: 10163244, RES: 367144
2015-11-26 14:33:02+00:00 VIRT: 10302576, RES: 367820
2015-11-26 14:33:03+00:00 VIRT: 10441908, RES: 368664
2015-11-26 14:33:04+00:00 VIRT: 10589436, RES: 368868
2015-11-26 14:33:05+00:00 VIRT: 3229428, RES: 358896
2015-11-26 14:33:06+00:00 VIRT: 3098292, RES: 359452
2015-11-26 14:33:08+00:00 VIRT: 2852412, RES: 359448
2015-11-26 14:33:09+00:00 VIRT: 2524572, RES: 359660
2015-11-26 14:33:10+00:00 VIRT: 2524572, RES: 359660
2015-11-26 14:33:11+00:00 VIRT: 2524572, RES: 359660
........
2015-11-26 14:54:01+00:00 VIRT: 2524572, RES: 359660
2015-11-26 14:54:02+00:00 VIRT: 2524572, RES: 359660
2015-11-26 14:54:03+00:00 VIRT: 2524572, RES: 359660
2015-11-26 14:54:04+00:00 VIRT: 2524572, RES: 359660
There is a problem only when the long run many parallel threads!
This test on C language max memory usage 9Kb, min 1 Kb.
In PHP $threads array only using 162Kb memory. Why the process using 109Mb for test PHP7 and 352Mb for test PHP5?
You are creating 1000 instances of the interpreter. You can expect 1000 threads to use about as much memory as 1000 processes executing the same code, actually a little more.
I think you are expecting them to share address space and so you are not expecting more threads to mean more memory, well it does for PHP. PHP is shared nothing and pthreads can't break that.
C and PHP manage memory very differently, you are comparing apples and oranges there.
You should not create threads and destroy them, only to recreate them later on in the process, you should reuse them. This is what Worker
and Pool
are aimed at.
1000 threads isn't a sensible number of threads to create on any hardware, these are kernel threads, and it'll be a long time before we can access processors capable of executing 1000 threads concurrently.
Design your infrastructure sensibly and this stuff isn't a problem.
Now I do not care about performance issues. My thread can use the CPU, or disk, or network, or all at once. This is only a test.
I am concerned about the stability and adequacy of the behavior of the PHP. This test shows that the PHP with pthreads behaves unstable with respect to memory. Exists memory leak.
I think, normal behavior is for the pool bad(only stable, not performance):
My test makes the following:
In the state 1 and 6 memory usage should be the same! The test work properly and nothing is violated.
For memory_get_usage, in state 1 using 353 Kb and in state 6 is also using 353 Kb. This is Good!
But for PS linux command, in state 1 using 30 Mb and in state 6 using 108 Mb. This is not normal :-(. In the state 6 should be also 30Mb.
What kind of data is occupied by the memory?
Not all memory allocated is included in the value returned by `memory_get_usage``, only memory allocated by Zend's mm, and in addition, only memory allocated for the instance of the interpreter that called the function (each instance has it's own heap).
This doesn't include a lot of the memory allocated for modules globals and other stuff required for the interpreter to work.
It is very normal for the system and memory_get_usage
to disagree about memory usage, very normal.
Whenever you start a new thread, the interpreter must be initialized for the new thread, but may not have all resources that were allocated free'd until the whole process is shutdown.
It is very normal for the system and memory_get_usage to disagree about memory usage, very normal.
I agree
but may not have all resources that were allocated free'd until the whole process is shutdown.
This not normal. This is mistake. This is a memory leak. All resources must be freed!
I using valgrind for detect memory leak:
$ export ZEND_DONT_UNLOAD_MODULES=1 && valgrind --max-threads=2000 --leak-check=full --show-leak-kinds=all --leak-resolution=high --allow-mismatched-debuginfo=yes zts-php test.php
==19368== Memcheck, a memory error detector
==19368== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==19368== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==19368== Command: zts-php test.php
==19368==
==19368==
==19368== HEAP SUMMARY:
==19368== in use at exit: 2,601,658 bytes in 27,499 blocks
==19368== total heap usage: 3,598,451 allocs, 3,570,952 frees, 831,973,823 bytes allocated
==19368==
==19368== 96 bytes in 1 blocks are possibly lost in loss record 83 of 183
==19368== at 0x4C2A9C7: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19368== by 0x15F24478: UnknownInlinedFun (copy.h:287)
==19368== by 0x15F24478: pthreads_copy_function (copy.h:306)
==19368== by 0x15F255B1: pthreads_copy_entry (prepare.c:169)
==19368== by 0x15F255B1: pthreads_prepared_entry (prepare.c:396)
==19368== by 0x15F278FA: pthreads_prepare_classes (prepare.c:567)
==19368== by 0x15F278FA: pthreads_prepared_startup (prepare.c:680)
==19368== by 0x15F2C180: pthreads_routine (object.c:482)
==19368== by 0x7DDD609: start_thread (pthread_create.c:334)
==19368== by 0x80F5A7C: clone (clone.S:109)
==19368==
==19368== 73,728 bytes in 1 blocks are possibly lost in loss record 182 of 183
==19368== at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19368== by 0x345138: __zend_malloc (zend_alloc.c:2852)
==19368== by 0x37A75C: zend_hash_do_resize (zend_hash.c:854)
==19368== by 0x37D41F: _zend_hash_index_add_or_update_i (zend_hash.c:783)
==19368== by 0x37D41F: _zend_hash_index_update (zend_hash.c:825)
==19368== by 0x15F24045: UnknownInlinedFun (zend_hash.h:609)
==19368== by 0x15F24045: pthreads_globals_object_alloc (globals.c:82)
==19368== by 0x15F2BE3A: pthreads_thread_ctor (object.c:138)
==19368== by 0x37015A: _object_and_properties_init (zend_API.c:1300)
==19368== by 0x15F2C274: pthreads_routine (object.c:486)
==19368== by 0x7DDD609: start_thread (pthread_create.c:334)
==19368== by 0x80F5A7C: clone (clone.S:109)
==19368==
==19368== 2,207,904 (2,207,328 direct, 576 indirect) bytes in 22,993 blocks are definitely lost in loss record 183 of 183
==19368== at 0x4C2A9C7: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19368== by 0x15F24478: UnknownInlinedFun (copy.h:287)
==19368== by 0x15F24478: pthreads_copy_function (copy.h:306)
==19368== by 0x15F255B1: pthreads_copy_entry (prepare.c:169)
==19368== by 0x15F255B1: pthreads_prepared_entry (prepare.c:396)
==19368== by 0x15F278FA: pthreads_prepare_classes (prepare.c:567)
==19368== by 0x15F278FA: pthreads_prepared_startup (prepare.c:680)
==19368== by 0x15F2C180: pthreads_routine (object.c:482)
==19368== by 0x7DDD609: start_thread (pthread_create.c:334)
==19368== by 0x80F5A7C: clone (clone.S:109)
==19368==
==19368== LEAK SUMMARY:
==19368== definitely lost: 2,207,328 bytes in 22,993 blocks
==19368== indirectly lost: 576 bytes in 6 blocks
==19368== possibly lost: 73,824 bytes in 2 blocks
==19368== still reachable: 319,930 bytes in 4,498 blocks
==19368== suppressed: 0 bytes in 0 blocks
==19368== Reachable blocks (those to which a pointer was found) are not shown.
==19368== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==19368==
==19368== For counts of detected and suppressed errors, rerun with: -v
==19368== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
$ export ZEND_DONT_UNLOAD_MODULES=1 && valgrind --tool=helgrind --max-threads=2000 zts-php test.php
.....
==19870== ----------------------------------------------------------------
==19870==
==19870== Possible data race during read of size 8 at 0x936B108 by thread #3
==19870== Locks held: none
==19870== at 0x3814AB: UnknownInlinedFun (zend_string.h:84)
==19870== by 0x3814AB: zend_hash_find_bucket (zend_hash.c:469)
==19870== by 0x3814AB: zend_hash_find (zend_hash.c:1926)
==19870== by 0x15F26234: UnknownInlinedFun (zend_hash.h:671)
==19870== by 0x15F26234: pthreads_routine_run_function (object.c:449)
==19870== by 0x15F32296: pthreads_routine (object.c:487)
==19870== by 0x4C2F967: ??? (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x7DE3609: start_thread (pthread_create.c:334)
==19870== by 0x80FBA7C: clone (clone.S:109)
==19870==
==19870== This conflicts with a previous write of size 8 by thread #2
==19870== Locks held: none
==19870== at 0x381500: UnknownInlinedFun (zend_string.h:85)
==19870== by 0x381500: zend_hash_find_bucket (zend_hash.c:469)
==19870== by 0x381500: zend_hash_find (zend_hash.c:1926)
==19870== by 0x15F26234: UnknownInlinedFun (zend_hash.h:671)
==19870== by 0x15F26234: pthreads_routine_run_function (object.c:449)
==19870== by 0x15F32296: pthreads_routine (object.c:487)
==19870== by 0x4C2F967: ??? (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x7DE3609: start_thread (pthread_create.c:334)
==19870== by 0x80FBA7C: clone (clone.S:109)
==19870== Address 0x936b108 is 8 bytes inside a block of size 32 alloc'd
==19870== at 0x4C2A070: malloc (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x345138: __zend_malloc (zend_alloc.c:2852)
==19870== by 0x15F29E63: UnknownInlinedFun (zend_string.h:121)
==19870== by 0x15F29E63: UnknownInlinedFun (zend_string.h:157)
==19870== by 0x15F29E63: pthreads_globals_init (globals.c:52)
==19870== by 0x15F28841: zm_startup_pthreads (php_pthreads.c:323)
==19870== by 0x3720C9: zend_startup_module_ex (zend_API.c:1841)
==19870== by 0x37FC3B: zend_hash_apply (zend_hash.c:1500)
==19870== by 0x372489: zend_startup_modules (zend_API.c:1967)
==19870== by 0x2FD412: php_module_startup (main.c:2194)
==19870== by 0x40C4BC: php_cli_startup (php_cli.c:423)
==19870== by 0x1D572A: main (php_cli.c:1325)
==19870== Block was alloc'd by thread #1
......
==19870== ----------------------------------------------------------------
==19870==
==19870== Lock at 0x935B328 was first observed
==19870== at 0x4C30BA3: pthread_mutex_init (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x15F294ED: pthreads_monitor_alloc (monitor.c:42)
==19870== by 0x15F29E3F: pthreads_globals_init (globals.c:37)
==19870== by 0x15F28841: zm_startup_pthreads (php_pthreads.c:323)
==19870== by 0x3720C9: zend_startup_module_ex (zend_API.c:1841)
==19870== by 0x37FC3B: zend_hash_apply (zend_hash.c:1500)
==19870== by 0x372489: zend_startup_modules (zend_API.c:1967)
==19870== by 0x2FD412: php_module_startup (main.c:2194)
==19870== by 0x40C4BC: php_cli_startup (php_cli.c:423)
==19870== by 0x1D572A: main (php_cli.c:1325)
==19870== Address 0x935b328 is 8 bytes inside a block of size 96 alloc'd
==19870== at 0x4C2BDE7: calloc (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x15F294C6: pthreads_monitor_alloc (monitor.c:33)
==19870== by 0x15F29E3F: pthreads_globals_init (globals.c:37)
==19870== by 0x15F28841: zm_startup_pthreads (php_pthreads.c:323)
==19870== by 0x3720C9: zend_startup_module_ex (zend_API.c:1841)
==19870== by 0x37FC3B: zend_hash_apply (zend_hash.c:1500)
==19870== by 0x372489: zend_startup_modules (zend_API.c:1967)
==19870== by 0x2FD412: php_module_startup (main.c:2194)
==19870== by 0x40C4BC: php_cli_startup (php_cli.c:423)
==19870== by 0x1D572A: main (php_cli.c:1325)
==19870== Block was alloc'd by thread #1
==19870==
==19870== Possible data race during read of size 1 at 0x20D4171C by thread #1
==19870== Locks held: none
==19870== at 0x4C2C873: ??? (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x4C2CB48: ??? (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x4C30C30: pthread_mutex_destroy (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x15F297DC: pthreads_monitor_free (monitor.c:126)
==19870== by 0x15F324D0: pthreads_routine_wait (object.c:127)
==19870== by 0x15F324D0: pthreads_start (object.c:380)
==19870== by 0x15F26F44: zim_Thread_start (thread.h:97)
==19870== by 0x35ADF9: dtrace_execute_internal (zend_dtrace.c:107)
==19870== by 0x3FA51C: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==19870== by 0x3B07EA: execute_ex (zend_vm_execute.h:414)
==19870== by 0x35AC7F: dtrace_execute_ex (zend_dtrace.c:83)
==19870== by 0x15F279C4: pthreads_execute_ex (php_pthreads.c:143)
==19870== by 0x40B9E8: zend_execute (zend_vm_execute.h:458)
==19870==
==19870== This conflicts with a previous write of size 4 by thread #25
==19870== Locks held: 1, at address 0x935B328
==19870== at 0x7DE6F21: __pthread_mutex_unlock_usercnt (pthread_mutex_unlock.c:76)
==19870== by 0x7DE6F21: pthread_mutex_unlock (pthread_mutex_unlock.c:315)
==19870== by 0x4C2D348: ??? (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x4C30C5C: pthread_mutex_unlock (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x15F2956C: pthreads_monitor_unlock (monitor.c:61)
==19870== by 0x15F2CD1C: pthreads_prepared_startup (prepare.c:687)
==19870== by 0x15F32180: pthreads_routine (object.c:482)
==19870== by 0x4C2F967: ??? (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x7DE3609: start_thread (pthread_create.c:334)
==19870== Address 0x20d4171c is 12 bytes inside a block of size 96 alloc'd
==19870== at 0x4C2BDE7: calloc (in /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
==19870== by 0x15F294C6: pthreads_monitor_alloc (monitor.c:33)
==19870== by 0x15F32400: pthreads_routine_init (object.c:118)
==19870== by 0x15F32400: pthreads_start (object.c:376)
==19870== by 0x15F26F44: zim_Thread_start (thread.h:97)
==19870== by 0x35ADF9: dtrace_execute_internal (zend_dtrace.c:107)
==19870== by 0x3FA51C: ZEND_DO_FCALL_SPEC_HANDLER (zend_vm_execute.h:844)
==19870== by 0x3B07EA: execute_ex (zend_vm_execute.h:414)
==19870== by 0x35AC7F: dtrace_execute_ex (zend_dtrace.c:83)
==19870== by 0x15F279C4: pthreads_execute_ex (php_pthreads.c:143)
==19870== by 0x40B9E8: zend_execute (zend_vm_execute.h:458)
==19870== by 0x36D146: zend_execute_scripts (zend.c:1428)
==19870== by 0x2FDF97: php_execute_script (main.c:2471)
==19870== Block was alloc'd by thread #1
.....
Perhaps because of the parallel execution of the same code on different cpu cores allocation takes slightly more than planned? It may be a problem in locks?
This not normal. This is mistake. This is a memory leak. All resources must be freed!
I've told you how it works ... there's no mistake, and no important leak ... relying on process shutdown to free some memory is something PHP has always done, and will always do ... nothing to do about it ...
Worth mentioning that PHP does make an effort to free all that it can, but it's sometimes the case that some third party API (for example libxml, curl) may not be able to free until process shutdown.
Hello.
I did the same examples in php and C.
PHP example:
C example:
Result PHP:
Result C:
In PHP memory is not freed! For PHP7:
For PHP5.5:
For C:
If you remove the sleep(2) in threads then memory freed: For PHP7:
For PHP5.5:
For C:
Tested on versions 2.0.11 and 3.1.3
This is a real problem for PHP demons!