mirror of
https://github.com/php/php-src.git
synced 2024-11-28 04:14:26 +08:00
Fixed bug #71818 (Memory leak when array altered in destructor)
This commit is contained in:
parent
bb2bafc7d0
commit
8fc934b0a1
1
NEWS
1
NEWS
@ -13,6 +13,7 @@ PHP NEWS
|
||||
. Fixed bug #72216 (Return by reference with finally is not memory safe).
|
||||
(Dmitry)
|
||||
. Fixed bug #72215 (Wrong return value if var modified in finally). (Dmitry)
|
||||
. Fixed bug #71818 (Memory leak when array altered in destructor). (Dmitry)
|
||||
. Fixed bug #71539 (Memory error on $arr[$a] =& $arr[$b] if RHS rehashes)
|
||||
(Dmitry, Nikita)
|
||||
. Added new constant PHP_FD_SETSIZE. (cmb)
|
||||
|
28
Zend/tests/bug71818.phpt
Normal file
28
Zend/tests/bug71818.phpt
Normal file
@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #71818 (Memory leak when array altered in destructor)
|
||||
--FILE--
|
||||
<?php
|
||||
class MemoryLeak
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->things[] = $this;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->things[] = null;
|
||||
}
|
||||
|
||||
private $things = [];
|
||||
}
|
||||
|
||||
ini_set('memory_limit', '10M');
|
||||
|
||||
for ($i = 0; $i < 100000; ++$i) {
|
||||
$obj = new MemoryLeak();
|
||||
}
|
||||
echo "OK\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
OK
|
@ -735,7 +735,6 @@ static void gc_add_garbage(zend_refcounted *ref, gc_additional_buffer **addition
|
||||
GC_TYPE(ref) |= GC_FAKE_BUFFER_FLAG;
|
||||
}
|
||||
if (buf) {
|
||||
GC_REFCOUNT(ref)++;
|
||||
buf->ref = ref;
|
||||
buf->next = GC_G(roots).next;
|
||||
buf->prev = &GC_G(roots);
|
||||
@ -898,7 +897,6 @@ static int gc_collect_roots(uint32_t *flags, gc_additional_buffer **additional_b
|
||||
|
||||
current = GC_G(roots).next;
|
||||
while (current != &GC_G(roots)) {
|
||||
GC_REFCOUNT(current->ref)++;
|
||||
if (GC_REF_GET_COLOR(current->ref) == GC_WHITE) {
|
||||
count += gc_collect_white(current->ref, flags, additional_buffer);
|
||||
}
|
||||
@ -939,7 +937,6 @@ tail_call:
|
||||
GC_REF_GET_COLOR(ref) == GC_BLACK &&
|
||||
GC_ADDRESS(GC_INFO(ref)) != GC_ROOT_BUFFER_MAX_ENTRIES)) {
|
||||
GC_TRACE_REF(ref, "removing from buffer");
|
||||
GC_REFCOUNT(ref)--;
|
||||
if (root) {
|
||||
GC_INFO(ref) = 0;
|
||||
GC_REMOVE_FROM_ROOTS(root);
|
||||
|
Loading…
Reference in New Issue
Block a user