我有一个大型JSON文件列表(最小文件是500 Ko,最大文件是100 Mo).
我需要独立处理每个文件.我的问题是每个文件后内存使用量越来越多,即使我清除了所有内存.
例:
foreach ($files as $file) {
json_decode(file_get_contents($file->getRealpath()), true);
$memory = memory_get_usage(true);
echo 'Memory: '.@round($memory / pow(1024,($i=floor(log($memory, 1024)))), 2).' '.['b', 'kb', 'mb', 'gb', 'tb', 'pb'][$i]."\n";
gc_collect_cycles();
}
Run Code Online (Sandbox Code Playgroud)
结果:
Memory: 6 mb
(...)
Memory: 6 mb
Memory: 6 mb
Memory: 10 mb
Memory: 10 mb
Memory: 10 mb
(...)
Memory: 12 mb
Memory: 12 mb
Memory: 12 mb
(...)
Memory: 490 mb
Memory: 490 mb
Memory: 490 mb
(...)
Memory: 946 mb
Memory: 944 mb
Memory: 944 mb
(...)
Run Code Online (Sandbox Code Playgroud)
内存越来越多,直到PHP告诉我他无法获得更多.正如你所看到的,除了json_decode(),没有赋值变量或其他任何东西,我在这个例子中什么都不做.那么为什么我的记忆会像这样增长,我该如何清除呢?
检查您尝试获取内容的文件的大小。这可能会更大,因此会消耗内存
或者
您需要检查哪个变量持有过多的内存,您可以使用strlen()它不会给您 var 持有的确切内存,但长度有助于找到近似值。
并且您应该将unset未使用的变量清除内存。
unset($decoded_data);
Run Code Online (Sandbox Code Playgroud)
或设置
$var = null
当您使用 unset 时,只有垃圾收集器决定时才会释放内存,但是当您将变量设置为不同的值(在本例中为 null)时,您可能会释放一些内存,当然会释放 CPU 的成本。
我会推荐你使用
https://github.com/salsify/jsonstreamingparser
这是一个简单的流式解析器,用于处理大型 JSON 文档。使用它来解析非常大的 JSON 文档,以避免将整个内容加载到内存中,这就是几乎所有其他 PHP JSON 解析器的工作原理。