Closed taowen closed 7 years ago
call zend_hash_str_del(&EG(symbol_table), name, strlen(name));
to remove bind name from symbol table seems like fixed the problem. Isn't the value destroy too brute force?
Possibly so, I'll need to delve into this a bit more since the semantics between what gets de-allocated when destroying values and contexts are still unclear to me... The current implementation does a zval_dtor
, which seems to be the right thing to do, but maybe not.
I have found a fix for this problem. It is in my branch: https://github.com/taowen/go-php/blob/memory-leak-fix/engine/value.go
Array/Map works like a container owning its element. So when add zval to it, and it can keep track of its lifetime. However object property assignment is a copy of value, so after assign it, we need to free the zval created before, https://github.com/taowen/go-php/blob/memory-leak-fix/engine/value.go#L139
When a zval is added to symbol table. We no longer need to call zval_dtor. The zend vm will tear down the symbol table properly after shutdown. So, we just skip the destroying the value. Think context.bind as passing the memory ownership.
Because the engine_value itself is heap allocated. value_destroy will destroy the zval and engine_value wrapper heap memory. Sometime, we just want to destroy the wrapper, leaving the zval managed by the zend vm. It is too hard to keep track of two piece of memory (just like why zval instead zval* from php5 to php7). I just dropped the wrapper all together, using zval directly.
Now, I think all memory problem goes away. I am heading to create a php7 only version of this. It is just too much work to support both php5 and php7.
when the values destroyed, then the context destroy will trigger gc_possible_root assertion error. Found in php-7.0.12
Complete error message