简体   繁体   English

PHP异常内存泄漏

[英]PHP Exception memory leak

In my console application, I replaced displaying all PHP built-in error types with throwing ErrorException : 在我的控制台应用程序中,我将显示所有PHP内置错误类型的显示替换为抛出ErrorException

set_error_handler(function ($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        // This error code is not included in error_reporting
        return;
    }

    throw new ErrorException($message, 0, $severity, $file, $line);
});

It works great, but there's one problem. 它很好用,但是有一个问题。 Consider the following snippet: 考虑以下代码段:

for ($id = 1;; $id += 1) {
    try {
        $html = file_get_contents('https://stackoverflow.com/boo/' . $id);
    } catch (Exception $exception) {
        // Failed
    }
}

Every ErrorException thrown keeps the stack history. 抛出的每个ErrorException保留堆栈历史记录。 In real-life example, some IDs are missing and that causes, so after thousands of iterations, eventually the memory leak occurs. 在实际示例中,缺少某些ID,这会导致这种情况,因此在进行数千次迭代之后,最终会发生内存泄漏。

What can be done to fix this problem? 如何解决此问题? Is throwing and catching exceptions is a loop wrong? 抛出和捕获异常是循环错误吗? Or maybe I could disable the stacking behavior somehow? 还是我可以以某种方式禁用堆叠行为?

You can unset the Exception object once you've used it on each iteration: 一旦在每次迭代中使用了Exception对象,就可以取消设置它:

function getLevels($start_idx,$levels = 9){
   try {
            return $this->getBinaryTree($levels);
        } catch (Exception $e) {
            switch($e->getMessage()){
            case "Almost out of memory":
               $max_tree_depth = (int)($levels/2);
               if($max_tree_depth >= 2){
                    unset($e); // <------------------------ RIGHT HERE!
                    return $this->getLevels($start_idx,$max_tree_depth);
               }else{
                    throw new Exception("Out of memory even after getting tree with 2 levels");
               }
               break;
            default:
               throw $e;
         }
     }
}

I found the solution on the link below: 我在下面的链接上找到了解决方案:

https://stuporglue.org/php-memory-leak-when-throwing-catching-and-recursing/ https://stuporglue.org/php-memory-leak-when-throwing-catching-and-recursing/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM