file_get_contents() 使用的内存在未分配给变量时是否会被释放?

发布于 2024-07-12 13:57:51 字数 249 浏览 3 评论 0原文

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

例如:

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

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

When I use file_get_contents and pass it as a parameter to another function, without assigning it to a variable, does that memory get released before the script execution finishes?

For Example:

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

Will the memory used by file_get_contents be released before the script finishes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

红焚 2024-07-19 13:57:51

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

方法 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 函数调用后立即被销毁。

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

这是另一种方法,它使用 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

The temporary string created to hold the file contents will be destroyed. Without delving into the sources to confirm, here's a couple of ways you can test that a temporary value created as a function parameter gets destroyed:

Method 1: a class which reports its destruction

This demonstrates lifetime by using a class which reports on its own demise:

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";

This outputs

Calling foo
construct
inside foo
destruct
foo complete

Which indicates that the implied temporary variable is destroyed right after the foo function call.

Method 2: measure memory usage

Here's another method which offers further confirmation using memory_get_usage to measure how much we've consumed.

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";

This outputs

start: 50672
in foo: data is 2999384, memory usage=3050884
end: 51544
一紙繁鸢 2024-07-19 13:57:51

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

In your example the memory will be released when $matches goes out of scope.
If you weren't storing the result of the match the memory would be released immediately

土豪 2024-07-19 13:57:51

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

start: 1050504

end: 6492344

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

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

start = 1050504

end = 1050976

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

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

In following code memory usage = 6493720

start: 1050504

end: 6492344

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

but memory usage in following code = 1049680

start = 1050504

end = 1050976

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

Note: in first code file stores in a variable.

绝情姑娘 2024-07-19 13:57:51

如果您认为这将有助于避免内存不足错误,那么您就错了。 您的代码(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 参数或分块读取文件

If you think this will help in avoiding insufficient memory errors you are wrong. Your code (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;
?>

uses 10.5 MB:

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

and this code:

<?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;
?>

uses 10.5 MB as well:

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

If you like to guard your script you need to use the $length parameter or read the file in chunks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文