2009-09-03 4 views
3

Я пытаюсь избежать утечки памяти в PHP. Когда я создаю объект и отключаю его в конце, он все еще находится в памяти. Сброс выглядит следующим образом:Утечка памяти и fork памяти

$obj = NULL; 
unset($obj); 

Все еще это не поможет.

Мой вопрос в том, что произойдет, когда я проработаю proccess, и объект будет создан и уничтожен в дочернем потоке? Это будет то же самое? Или есть ли другой способ, как освободить память?

Это сценарий импорта, который будет потреблять несколько концертов.

ответ

12

PHP 5.3 имеет сборщик мусора, который может собирать циклические ссылки. Это может быть стоит попробовать:

gc_enable(); 

class A { 
    public function __construct() { 
    $this->data = str_repeat("A", 1024000); 
    } 
} 

$mem = memory_get_usage(); 
$a = new A(); 
$mem2 = memory_get_usage(); 
$a->a = $a; 
$a->a->mydata = $a->data . 'test'; 
$mem3 = memory_get_usage(); 
unset($a); 
gc_collect_cycles(); 
$mem4 = memory_get_usage();  

printf("MEM 1 at start %0.2f Mb\n", ($mem/1024)/1024); 
printf("MEM 2 after first instantiation %0.2f Mb\n", ($mem2/1024)/1024); 
printf("MEM 3 after self-ref: %0.2f Mb\n", ($mem3/1024)/1024); 
printf("MEM 4 after unset(\$a): %0.2f Mb\n", ($mem4/1024)/1024);  

Выход:

MEM 1 at start: 0.31 Mb 
MEM 2 after first instantiation: 1.29 Mb 
MEM 3 after self-ref: 2.26 Mb 
MEM 4 after unset($a): 0.31 Mb 
+0

+1, хорошие данные примера –

5

Не нужно устанавливать переменную в NULL перед вызовом unset() на ней. Обратите внимание, однако, что unset() не освобождает память. Главное, что вы можете проверить, это то, что ваш объект удаляет любые ссылки . должен иметь большие куски данных, прежде чем вы его удалите.

1

хорошо ваш скрипт импорта не следует использовать несколько гигабайт оперативной памяти в первую очередь. попробуйте хранить большие куски данных в другом месте (файловой системе или БД), когда вы не нуждаетесь в нем. Также подумайте об импорте небольших разделов за раз, а не в одном большом куске, даже если это займет больше времени, но таким образом вы будете компенсировать большое потребление памяти.

Что вы говорите, это не утечка памяти, поскольку это документированное, хорошо известное поведение. Как сказал MathieuK, в PHP5.3 вы можете использовать некоторые функции gc *, но я их никогда не тестировал. PHP - довольно плохой язык для обработки временных больших фрагментов данных, потому что после выделения выделенная память больше никогда не будет освобождена, даже если вы ее отключите (это связано с тем, что выделенная память будет повторно использована, и это это хорошо на веб-странице, но не очень хорошо в большом «хардкорном» скрипте ..).

Смежные вопросы