You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
op_arrays with temporary run_time_cache leak memory when observed #8082
<?php$closure = function() { /* observe this */ };
$object = newclass {};
$mem = memory_get_usage();
while (true) {
if ($mem != memory_get_usage()) {
var_dump($mem = memory_get_usage());
}
$closure->call($object);
}
To reproduce, run with php -dzend_test.observer.enabled=1 -dzend_test.observer.observe_all=1 -dzend_test.observer.show_output=0 and see memory consumption explode.
PHP Version
PHP8.0 - master
Analysis
Observing op_arrays arena allocates some memory, which is never freed, even if the specific op_array (or more precisely run_time_cache) is freed.
We are constrained by the fact that run_time_cache is caller managed memory currently. Doing something else is an ABI or API break and not viable in PHP 8.0 or 8.1.
The only solution which comes to my mind is allocating enough space in the run_time_cache (e.g. at its end) to fit handlers there, i.e. 16 bytes (two pointers, start and end) per registered observing initializer instead of arena allocating that memory. This would be achieved by an increase of cache_size by the appropriate amount then.
This should also be safe regarding the application interface, especially given that the structs are not exported.
For PHP 8.2 one might consider a cleaner solution then.
Activity
Fix GH-8082: Prevent leaking memory on observed transient run_time_ca…