I am making a big PHP array and then remove most of the beginning of it. As we know it won't free the memory only mark removed items as Undef, as explained by Nikita here. However when I put more items to the array it should reach the compaction point and we should see memory reduction, but that is not observed.
Please help to understand why compaction is not happening?
<?php
$items = [];
// hashtable compaction should start at every 2^n size.
$size = pow(2, 18);
for($i=0;$i<$size;$i++) {
$items[$i] = "string $i";
}
// at this point we reached the maximum tablesize before compaction
// 2^18 is used to make memory consumpotion visible enough.
printf("mem: %d Mb \n", memory_get_usage(true) / 1024 / 1024);
// Remove all except the last one
for($i=0;$i<$size-1;$i++) {
unset($items[$i]);
}
// here it is expected to see the same memory footprint as nothing is freed,
// only marked as UNDEF.
printf("mem: %d Mb \n", memory_get_usage(true) / 1024 / 1024);
// However here we expect to hit the compaction point
// and see $size-1 elements removed, while 1 added, so memory is expected to go down
$items[] = $i;
printf("mem: %d Mb \n", memory_get_usage(true) / 1024 / 1024);
Live example: https://onlinephp.io/c/98970
memory_get_usage(false)to view the actual memory usage. You created a packed hashtable, appending an element can lead to memory growth instead. And the most crucial thing is "arData never shrinks".