Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么在匿名函数上使用“unset”时使用“eval”不会释放内存?_Php_Apache - Fatal编程技术网

Php 为什么在匿名函数上使用“unset”时使用“eval”不会释放内存?

Php 为什么在匿名函数上使用“unset”时使用“eval”不会释放内存?,php,apache,Php,Apache,下面非常简单的PHP代码工作得非常完美,我的意思是,它什么都不做,同时几乎不使用任何系统内存 <?php set_time_limit(0); ini_set('memory_limit','-1'); for ($i=0;$i<100000000;$i++) { $bbb = function() { return true; }; unset($bbb); } ?> “test.ph

下面非常简单的PHP代码工作得非常完美,我的意思是,它什么都不做,同时几乎不使用任何系统内存

<?php

set_time_limit(0); 
ini_set('memory_limit','-1');

for ($i=0;$i<100000000;$i++) {
        
    $bbb = function() {
    
        return true;

    };

    unset($bbb);
    
}

?>
“test.php”文件包含以下内容:

<?php

$bbb = function() {

    return true;

};

?>


但是这个建议仍然会消耗大量内存,它不会被清除!即使我使用
gc_mem_caches()GC仍然没有清除内存。也许我从你的建议中理解了一些错误@@Nigel Ren?

请参阅Chris on的最后一句评论

为了子孙后代,我将把它复制到这里:

我最近对eval()行为很感兴趣,我可以确认执行时内存使用率会越来越高。 然而,这并不是一个真正的bug,而是eval()的基本编写方式:

  • 它创建一个包含代码的临时文件(有时存储在内存中)
  • 然后使用普通的include()函数包含该临时文件
如您所见,eval()越多,它触发的include()越多,导致无法释放的内存使用

因此,使用
eval
时内存使用量增加的原因是它包含临时文件。有一种方法可以取消包含文件,因此您使用的
eval
越多,最终使用的内存就越多

免责声明:以下纯属猜测,我尚未验证这是否有效

至于解决这个问题的潜在解决方法,因为您说需要使用
eval
,所以您可以研究使用fork来派生流程


它可能会慢一些,但是如果您可以将
eval
-ing代码段转移到一个单独的进程,该进程可以在完成后优雅地终止,那么在该子进程中执行的“include”应该被清除。这可能是限制应用程序内存使用的一种方法。

作为测试,此代码从第一个列表中的源代码模板开始,减去定义,但用一个占位符插入代码。脚本只是读取这个文件,用AI脚本替换标记并编写一个新文件(abc1.php),然后使用
require
运行脚本。这消除了对
eval
的任何需要以及与之相关的日常开支

所以abc.php是

set_time_limit(0);
ini_set('memory_limit','-1');

for ($i=0;$i<10;$i++) {
    
    //#
    
    unset($bbb);
    
}
在此之后,脚本abc1.php包含

set_time_limit(0);
ini_set('memory_limit','-1');

for ($i=0;$i<10;$i++) {
    
    $bbb = function() {
    
        echo "Hello";

    };

$bbb();
    
    unset($bbb);
    
}
设置时间限制(0);
ini_集('内存限制','-1');

对于($i=0;$i经过大量的重新搜索,我发现runkit7是一个不错的选择!它甚至可以从包含/需要/评估的函数中清除RAM!你可以使用包含/需要/评估,它将明智地清理内存占用。这是一个非常棒的扩展,我一测试它就感到惊讶,我的RAM比上一次运行时下降了90%没有runkit7。

谢谢,这看起来不错,但不幸的是,你的解决方案并没有解决我的问题,因为我运行了数十亿次代码,每次都会产生一个新的进程来评估,这将对我的运行时间产生巨大影响。如果我将循环时间增加一个秒,我已经在Linode上以每月近2k美元的价格租了一台机器小分数,它会打破银行!如果你能找到另一种方法让我声明一个函数并能够取消它的显示,我会很高兴!如果你能找到更好的答案,你的答案肯定会被接受!你能操纵运行代码的脚本文件吗?所以,你可以将代码粘贴到脚本中然后运行它,而不是
eval
o你的意思是“AI输出”@NigelRen如果你认为有帮助,我可以将代码粘贴到脚本中并运行它。这将如何解决我的问题?@Olivier AI生成PHP代码,稍后我需要对其进行评估以检查精度。但“AI”是什么这是一个非常好的主意!我想它甚至可能比我的eval运行得更快,因为eval太慢了!我现在就试试!你能阅读我的编辑吗?我不能在评论中用代码回复你,所以我把它贴在我问题的底部好吗?我遗漏了什么吗?@Samul这段代码仍然使用了大量的
要求
e其他答案:“它将触发的include()越多,导致无法释放的内存使用”@Olivier根据你最后的评论,根据我在这个问题上得到的第一个答案,
include
require
…中包含的任何内容都不会被PHP清除,即使在取消了其中的所有变量/函数之后?@Samul确实令人惊讶,但似乎
include
会造成泄漏。
set_time_limit(0);
ini_set('memory_limit','-1');

for ($i=0;$i<10;$i++) {
    
    //#
    
    unset($bbb);
    
}
$src = file_get_contents("abc.php");
$aiSrc = '$bbb = function() {
    
        echo "Hello";

    };

$bbb();';

$newSrc = str_replace("//#", $aiSrc, $src);
file_put_contents("abc1.php", $newSrc);

require"abc1.php";
set_time_limit(0);
ini_set('memory_limit','-1');

for ($i=0;$i<10;$i++) {
    
    $bbb = function() {
    
        echo "Hello";

    };

$bbb();
    
    unset($bbb);
    
}