首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在PHP中安全地捕获“允许的内存大小耗尽”错误

在PHP中安全地捕获“允许的内存大小耗尽”错误
EN

Stack Overflow用户
提问于 2011-12-09 10:49:35
回答 3查看 45.4K关注 0票数 80

我有一个网关脚本,它将JSON返回给客户机。在脚本中,我使用set_error_handler来捕获错误,但仍然有一个格式化的返回。

它会受到“允许的内存大小耗尽”错误的影响,而不是像ini_set('memory_limit', '19T')这样的东西来增加内存限制,我只想返回用户应该尝试其他东西,因为它使用了很多内存。

有没有什么好方法来捕捉致命的错误?

EN

回答 3

Stack Overflow用户

发布于 2014-12-21 00:05:04

如果在发生此错误时需要执行业务代码(日志记录、为将来的调试备份上下文、发送电子邮件等),注册一个关闭函数是不够的:您应该以某种方式释放内存。

一种解决方案是在某个地方分配一些紧急内存:

代码语言:javascript
复制
public function initErrorHandler()
{
    // This storage is freed on error (case of allowed memory exhausted)
    $this->memory = str_repeat('*', 1024 * 1024);

    register_shutdown_function(function()
    {
        $this->memory = null;
        if ((!is_null($err = error_get_last())) && (!in_array($err['type'], array (E_NOTICE, E_WARNING))))
        {
           // $this->emergencyMethod($err);
        }
    });
    return $this;
}
票数 46
EN

Stack Overflow用户

发布于 2011-12-09 10:59:06

你可以通过使用这个函数得到进程已经消耗的内存大小,memory_get_peak_usage文档在http://www.php.net/manual/en/function.memory-get-peak-usage.php上,我认为如果你可以在进程几乎达到内存限制之前添加一个条件来重定向或停止进程,这将会更容易。:)

票数 8
EN

Stack Overflow用户

发布于 2018-06-08 01:52:51

虽然@alain-tiemblo解决方案运行良好,但我把这个脚本放在php脚本中展示了如何在对象作用域之外保留一些内存。

简短版本

代码语言:javascript
复制
// memory is an object and it is passed by reference
function shutdown($memory) {
    // unsetting $memory does not free up memory
    // I also tried unsetting a global variable which did not free up the memory
    unset($memory->reserve);
}

$memory = new stdClass();
// reserve 3 mega bytes
$memory->reserve = str_repeat('❤', 1024 * 1024);

register_shutdown_function('shutdown', $memory);

完整的示例脚本

代码语言:javascript
复制
<?php

function getMemory(){
    return ((int) (memory_get_usage() / 1024)) . 'KB';
}

// memory is an object and it is passed by reference
function shutdown($memory) {
    echo 'Start Shut Down: ' . getMemory() . PHP_EOL;

    // unsetting $memory does not free up memory
    // I also tried unsetting a global variable which did not free up the memory
    unset($memory->reserve);

    echo 'End Shut Down: ' . getMemory() . PHP_EOL;
}

echo 'Start: ' . getMemory() . PHP_EOL;

$memory = new stdClass();
// reserve 3 mega bytes
$memory->reserve = str_repeat('❤', 1024 * 1024);

echo 'After Reserving: ' . getMemory() . PHP_EOL;

unset($memory);

echo 'After Unsetting: ' . getMemory() . PHP_EOL;

$memory = new stdClass();
// reserve 3 mega bytes
$memory->reserve = str_repeat('❤', 1024 * 1024);

echo 'After Reserving again: ' . getMemory() . PHP_EOL;

// passing $memory object to shut down function
register_shutdown_function('shutdown', $memory);

输出结果为:

代码语言:javascript
复制
Start: 349KB
After Reserving: 3426KB
After Unsetting: 349KB
After Reserving again: 3426KB
Start Shut Down: 3420KB
End Shut Down: 344KB
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8440439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档