3

我正在使用一个 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.

可能是什么问题呢?如何在退出时释放内存?请帮忙谢谢!

4

4 回答 4

2

这似乎是 PHP 的一个已知方面,并且根据肯定比我知识多得多的人的说法,这是一种故意的。有人有一个完全相同的问题(http://comments.gmane.org/gmane.comp.php.devel/77918),事实证明他们是故意这样做的:

我们确实有一些故意泄漏,我们依赖池分配器在请求结束时擦除内容。因此,与您在请求中发现一个请求相比,我不太关心您在请求终止时看到的内容。

希望这对您的问题有所启发。

于 2013-02-26T23:53:50.893 回答
1

我能够重现您的错误的唯一方法是每次存储一个值并将其长度$_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-27T00:47:43.030 回答
0

我认为您误解了导致内存泄漏的原因。如果您尝试将代码修改为以下代码,那么您将看到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-26T23:54:34.400 回答
0

伙计们谢谢你的帮助,我真的很感激。我很幸运我发现了这个问题。它可能是包含 ob_start() 的模板类的 render() 方法。因此,当在 mypage.php 中调用 exit() 函数时(包含在 render() 中)。输出缓冲区可能已耗尽。我不确定这可能是问题,但我能够通过更改执行模板->渲染()的顺序来解决问题;

多谢你们!!

于 2013-02-27T01:06:06.517 回答