Результат функции php exit() приводит к утечкам памяти

81
6

Я использую страницу для запросов ajax и внутри нее добавляю exit(); чтобы остановить загрузку шаблона, поскольку это запрос ajax.


Проблема заключается в том, что каждый раз, когда я добавляю exit(), память не освобождается. Я проверил память следующим образом:


//mypage.php
echo memory_get_usage(); exit(); // This results to memory to climb up for every page refresh.
===============================
//mypage.php
echo memory_get_usage(); // The memory is ok

//For clarification the above codes are executed at different times.


В чем может быть проблема? Как я могу освободить память при выходе? Помогите пожалуйста, спасибо!

спросил(а) 2013-02-27T02:47:00+04:00 7 лет, 8 месяцев назад
1
Решение
57

Единственный способ, которым я смог воспроизвести вашу ошибку, - это сохранить значение в $_SESSION и удвоить его длину каждый раз. Вот мой код:


<?php

session_start();

if (!isset($_SESSION['test'])) {
$_SESSION['test'] = 'abcdefghij';
}
else {
$_SESSION['test'] .= $_SESSION['test'];
}
$_SESSION['memory'][] = memory_get_usage();

print_r($_SESSION['memory']);
exit;


После обновления страницы 24 раза, я, наконец, получаю ее, чтобы не хватать памяти:


Array
(
[0] => 231768
[1] => 232088
[2] => 232248
[3] => 232424
[4] => 232640
[5] => 232728
[6] => 233200
[7] => 233984
[8] => 235376
[9] => 238136
[10] => 243392
[11] => 253768
[12] => 274384
[13] => 315480
[14] => 397536
[15] => 561512
[16] => 889328
[17] => 1544952
[18] => 2855808
[19] => 5477384
[20] => 10720400
[21] => 21206296
[22] => 42177952
[23] => 84121128
)
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 83886344 bytes) in Unknown on line 0

Вы можете видеть, что использование памяти увеличивается каждый раз, когда страница обновляется.


Когда вы укажете PHP на exit, он ничего не выполнит в вашем коде. Я предполагаю, что где-то после exit вы также делаете что-то вроде:


$_SESSION['test'] = 'something else';

Когда вы exit на странице, это не будет выполняться и, следовательно, превратит его в экспоненциально увеличивающийся цикл, увеличивая использование памяти каждый раз. Если вы не можете найти что-либо подобное, я бы рекомендовал изучить Xdebug, чтобы лучше понять, что происходит.

ответил(а) 2013-02-27T03:47:00+04:00 7 лет, 8 месяцев назад
70

Это, по-видимому, известный аспект PHP и, по мнению людей, обладающих определенными знаниями, чем я, он преднамерен. У кого-то был точно такой же вопрос (http://comments.gmane.org/gmane.comp.php.devel/77918), и, оказывается, они делают это нарочно:


У нас есть преднамеренные утечки, когда мы полагаемся на распределитель пула протирать вещи в конце запроса. Поэтому меня меньше беспокоит вещи, которые вы видите при завершении запроса, чем я, если бы вы нашли один середина запрос.


Надеюсь, что это светит на ваш вопрос.

ответил(а) 2013-02-27T02:53:00+04:00 7 лет, 8 месяцев назад
42

Ребята Спасибо за помощь, я действительно ценю это. Мне повезло, что я нашел проблему. Вероятно, это метод render() моего класса шаблонов, который содержит ob_start(). Поэтому, когда функция exit() вызывается в mypage.php(которая включена в render()). выходной буфер может быть исчерпан. Я не уверен, что это может быть проблемой, но я смог решить проблему, изменив последовательность выполнения шаблона- > render();


Спасибо, ребята!

ответил(а) 2013-02-27T04:06:00+04:00 7 лет, 8 месяцев назад
41

Я думаю, вы ошибаетесь в том, что вызывает утечку памяти. Если вы попытаетесь изменить свой код ниже, вы увидите, что после вызова exit ничего не запускается.


echo memory_get_usage(); exit(); // This results to memory to climb up for every page refresh.

echo "I will never echo". PHP_EOL;
echo memory_get_usage(); // The memory is ok


Чтобы отладить это правильно, я бы рекомендовал включить дополнительный дополнительный контекст отладки во всю вашу встроенную отладку, например:


echo "before database call: ". memory_get_usage() . PHP_EOL;

а затем из них выработать, где начинается использование памяти

ответил(а) 2013-02-27T02:54:00+04:00 7 лет, 8 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема