【问题标题】:Does the memory used by file_get_contents() get released when it is not assigned to a variable?file_get_contents() 使用的内存在未分配给变量时是否会被释放?
【发布时间】:2009-02-02 14:12:17
【问题描述】:

当我使用 file_get_contents 并将其作为参数传递给另一个函数而不将其分配给变量时,该内存是否会在脚本执行完成之前被释放?

例如:

preg_match($pattern, file_get_contents('http://domain.tld/path/to/file.ext'), $matches);

file_get_contents 使用的内存会在脚本完成前释放吗?

【问题讨论】:

  • 我知道这不是使用这些功能的最佳方式,但问题仍然存在。

标签: php memory-consumption


【解决方案1】:

为保存文件内容而创建的临时字符串将被销毁。无需深入研究来源进行确认,您可以通过以下几种方法测试作为函数参数创建的临时值是否被破坏:

方法1:报告其销毁的类

这通过使用报告其自身消亡的类来演示生命周期:

class lifetime
{
    public function __construct()
    {
         echo "construct\n";
    }
    public function __destruct()
    {
         echo "destruct\n";
    }


}

function getTestObject()
{
   return new lifetime();
}


function foo($obj)
{
   echo "inside foo\n";
}




echo "Calling foo\n";
foo(getTestObject());
echo "foo complete\n";

这个输出

Calling foo
construct
inside foo
destruct
foo complete

这表明隐含的临时变量 在 foo 函数调用之后立即被销毁。

方法二:测量内存使用情况

这是另一种方法,它使用memory_get_usage 提供进一步确认,以测量我们消耗了多少。

function foo($str)
{
   $length=strlen($str);

   echo "in foo: data is $length, memory usage=".memory_get_usage()."\n";
}

echo "start: ".memory_get_usage()."\n";
foo(file_get_contents('/tmp/three_megabyte_file'));
echo "end: ".memory_get_usage()."\n";

这个输出

start: 50672
in foo: data is 2999384, memory usage=3050884
end: 51544

【讨论】:

    【解决方案2】:

    在您的示例中,当$matches 超出范围时,内存将被释放。
    如果您不存储匹配结果,内存将立即释放

    【讨论】:

      【解决方案3】:

      在以下代码中内存使用 = 6493720

      开始:1050504

      结束:6492344

      echo "start: ".memory_get_usage()."\n";
      $data = file_get_contents("/six_megabyte_file");
      echo "end: ".memory_get_usage()."\n";
      

      但以下代码中的内存使用量 = 1049680

      开始 = 1050504

      结束 = 1050976

      echo "start: ".memory_get_usage()."\n";
      file_get_contents("/six_megabyte_file");
      echo "end: ".memory_get_usage()."\n";
      

      注意:在第一个代码文件中存储在一个变量中。

      【讨论】:

        【解决方案4】:

        如果您认为这将有助于避免内存不足错误,那您就错了。你的代码(bytes_format):

        <?php
        $url = 'http://speedtest.netcologne.de/test_10mb.bin';
        echo 'Before: ' . bytes_format(memory_get_usage()) . PHP_EOL;
        preg_match('~~', file_get_contents($url), $matches);
        echo 'After: ' . bytes_format(memory_get_usage()) . PHP_EOL;
        echo 'Peak: ' . bytes_format(memory_get_peak_usage(true)) . PHP_EOL;
        ?>
        

        使用 10.5 MB:

        Before: 215.41 KB
        After: 218.41 KB
        Peak: 10.5 MB
        

        还有这段代码:

        <?php
        $url = 'http://speedtest.netcologne.de/test_10mb.bin';
        echo 'Before: ' . bytes_format(memory_get_usage()) . PHP_EOL;
        $contents = file_get_contents($url);
        preg_match('~~', $contents, $matches);
        unset($contents);
        echo 'After: ' . bytes_format(memory_get_usage()) . PHP_EOL;
        echo 'Peak: ' . bytes_format(memory_get_peak_usage(true)) . PHP_EOL;
        ?>
        

        也使用 10.5 MB:

        Before: 215.13 KB
        After: 217.64 KB
        Peak: 10.5 MB
        

        如果您想保护您的脚本,您需要使用$length 参数或read the file in chunks

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-08-30
          • 2013-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多