PHP中文件处理程序的可用内存

时间:2015-03-11 01:18:01

标签: php file memory fopen fclose

最近我开始面临PHP中的内存管理问题。这对我来说是新的,因为我从来不需要在后台线程上长时间运行PHP脚本。所以,现在我正在研究这个主题,然后来到下面的简单脚本:

function w()
{
    $f = fopen('test1.txt', 'w+');
    fclose($f);
    unset($f);
}

$i = 0;
$max = 5;

echo 'Memory usage:<br><br>';
echo $i . ' - ' . memory_get_usage() . '<br>';
touch('test1.txt');

while(++$i < $max)
{
    w();
    echo $i . ' - ' . memory_get_usage() . '<br>';
}

它只会多次打开和关闭同一个文件,每次关闭后它会显示使用的内存。

正如您所看到的,即使在关闭和取消设置()处理程序之后,内存也不会丢失。似乎内部指针仍然保持着内存。我知道,它们只有几个字节,但如果它在后台线程上运行,即使是几个字节也会破坏脚本(这是我的真正目的)。

我尝试设置$ f = null但它消耗的内存更多(我不是疯了,请自己检查)!并且gc_collect_cycles()也没有用。

所以我的问题是:有没有办法完全释放文件处理程序的内存?

2 个答案:

答案 0 :(得分:0)

您可以分叉到子进程并让子进程打开文件。

这样,当孩子结束时,PHP垃圾收集过程将清除其所有资源。

Keep in mind, however that the child will have access to any resource created by the parent and he will also close them when he finishes.

更新后的帖子:

实际上,在通过命令行尝试你的脚本之后(我只是将其修改为迭代100次而不是5次),这就是我得到的:

Memory usage:
0 - 119384
1 - 119564
2 - 119564
3 - 119564
4 - 119564
5 - 119564
6 - 119564
7 - 119564
8 - 119564
9 - 119564
10 - 119564
11 - 119564
12 - 119564
13 - 119564
14 - 119564
15 - 119564
16 - 119564
17 - 119564
18 - 119564
19 - 119564
20 - 119564
21 - 119564
22 - 119564
23 - 119564
24 - 119564
25 - 119564
26 - 119564
27 - 119564
28 - 119564
29 - 119564
30 - 119564
31 - 119564
32 - 119564
33 - 119564
34 - 119564
35 - 119564
36 - 119564
37 - 119564
38 - 119564
39 - 119564
40 - 119564
41 - 119564
42 - 119564
43 - 119564
44 - 119564
45 - 119564
46 - 119564
47 - 119564
48 - 119564
49 - 119564
50 - 119564
51 - 119564
52 - 119564
53 - 119564
54 - 119564
55 - 119564
56 - 119564
57 - 119564
58 - 119564
59 - 119564
60 - 119564
61 - 119564
62 - 119564
63 - 119564
64 - 119564
65 - 119564
66 - 119564
67 - 119564
68 - 119564
69 - 119564
70 - 119564
71 - 119564
72 - 119564
73 - 119564
74 - 119564
75 - 119564
76 - 119564
77 - 119564
78 - 119564
79 - 119564
80 - 119564
81 - 119564
82 - 119564
83 - 119564
84 - 119564
85 - 119564
86 - 119564
87 - 119564
88 - 119564
89 - 119564
90 - 119564
91 - 119564
92 - 119564
93 - 119564
94 - 119564
95 - 119564
96 - 119564
97 - 119564
98 - 119564
99 - 119564

答案 1 :(得分:0)

内存和文件句柄没有问题:它必须位于脚本的其他位置。我运行了以下版本的代码(基本上创建了一个5000 .jpg个文件的数组:清除迭代器使用的内存,只留下内存中的数组。然后根据上面的脚本运行该文件列表。)

<?php

$i = 0;
$max = 5000;

$aFiles = array();

$it = new RecursiveDirectoryIterator("d:/");
foreach(new RecursiveIteratorIterator($it) as $file) {
    if (strcmp(substr($file, -4), '.jpg') == 0) {
        if ($i++ > $max) {
            break;
        }
        $aFiles[] = $file;
    }
}
unset($it);
unset($max);

gc_collect_cycles();

$i = 0;
echo 'Memory usage:<br><br>';
echo $i . ' - ' . number_format(memory_get_usage()) . '<br>';

foreach($aFiles as $file) {
    $f = fopen($file, 'r');
    fclose($f);
    unset($f);
    echo ++$i . ' - ' . number_format(memory_get_usage()) . '<br>';
    flush(); // Trying to ensure that the output buffer doesn't add to memory
}

?>

以下是(截断的)结果:

Memory usage:

0 - 3,553,000
1 - 3,552,608
2 - 3,552,728
3 - 3,552,728
4 - 3,552,728
5 - 3,552,728
.....
4997 - 3,552,728
4998 - 3,552,728
4999 - 3,552,728
5000 - 3,552,728
5001 - 3,552,728

结论:问题将存在于其他地方。示例:没有flush(),在输出大约1K后内存会增加,因为它会为输出缓冲区添加更多内存。你能否确保没有其他因素可以解释被打开的内存,例如:你是否递归地调用open函数,每次都会添加到堆栈跟踪?