我有一个PHP脚本来取消一个网站(仅限文本文件)。运行几个小时后,我注意到脚本停止达到内存限制。我知道我可以增加限制,但是由于脚本加载的文件是纯文本HTML文件,我只解释了在每次循环后脚本无法清空内存时才达到限制。我是否可以通过定期刷新内存来优化脚本的内存管理?PHP脚本内存限制和内存优化
回答
您可以根据您不再需要的变量unset(例如unset($var)
或$var = null
)。如果您使用的是PHP 5.3或更高版本,则还可以显式调用垃圾收集器:请参阅gc_collect_cycles()和gc_enable()。
某些功能似乎比其他功能更差。我最近发现array_merge_recursive()
对我的代码的内存占用做了可怕的事情。
如果您希望能够分析内存正在运行的位置,则可以使用Xdebug或XHProf/XHGui等工具来提供帮助。例如Xdebug and tracing memory usage和Profiling with XHProf
参见:
请注意,PHP垃圾收集器仅用于**循环引用的特例;它不是** Zend引擎中的主要内存管理机制。 – IMSoP 2013-03-23 12:59:23
是的,好的,@IMSoP。更多信息请登录http://php.net/manual/en/features.gc.performance-considerations.php和http://php.net/manual/en/features.gc.collecting-cycles.php查看感兴趣的人。 – 2013-03-23 13:49:31
一般情况下,你不应该需要PHP手工管理内存,因为它内置了一个高层次的内存管理器到Zend引擎,为你照顾这件事。但是,了解一下这个过程是如何工作的,以便更好地理解你的代码为什么会耗尽内存是非常有用的。
由于是一个非常基本的概述,PHP根据有多少变量引用特定数据的“refcount”来释放内存。因此,如果你说$a = 'hello'; $b = $a;
,包含字符串'hello'
的单个内存将有一个2的refcount。如果你调用unset()
对任何变量,或者它们超出范围(例如在它们被定义的函数的末尾),该人数将减少。一旦refcount达到零,数据将被删除并释放内存。请注意,在这种情况下,“释放”意味着释放该PHP脚本的其他部分使用,不一定会释放回操作系统供其他进程使用。
有PHP版本价值之间的一些差异知道:
- 如果你有循环引用上述引用计数机制不起作用(如
$obj1->foo = $obj2; $obj2->bar = $obj1;
)因为引用计数永远不会到达零。在PHP 5.2及更早版本中,这意味着这样的循环引用导致内存泄漏,并且必须由程序员手动处理。在PHP 5.3中,"Garbage Collector"增加了专门处理这种情况。它不会取代正常的refcount机制,但是如果循环引用在您的代码中很常见,那么可能值得一读。 - PHP 5.4对PHP分配和使用内存的方式进行了大量优化。 AFAIK,这些都没有改变如何编写高效代码的基本建议,只要你愿意,它们只是升级你的PHP版本的一个很好的理由。
除此之外,还有编写PHP代码,使良好的使用内存的几个常见提示:
- 让当不再需要确保未使用的变量被丢弃。在一个结构良好的程序中,这通常不是问题,因为大多数变量对某个特定功能来说都是本地的;当函数退出时,它们将超出范围,并被释放。但是,如果您要创建大型中间变量,或动态创建大量变量,则手动调用
unset()
可能是个好主意。如果你的代码是非常线性的,或者使用大量的全局变量和静态变量,只需将它重构为更加模块化的结构就可以提高内存性能以及可读性,可维护性等。 - 指定或传递变量参考(
$foo = &$bar
)可能导致PHP使用更多内存比直接分配($foo = $bar
)。这是因为PHP使用“Copy On Write”机制将具有相同内容的变量存储在内存的一个位置,但引用分配与此机制冲突,因此PHP必须尽早复制该变量。 - 对象比标量值(int,boolean,string)或数组更需要内存。这是PHP 5.4中已经大大改进的一件事情,但仍值得思考 - 尽管显然不排除编写结构良好的代码!
- 1. PHP内存优化
- 2. 优化内存密集型脚本
- 3. PHP内存限制
- 4. PHP内存限制
- 5. PHP内存限制
- 6. PHP - 内存限制
- 7. PHP内存限制
- 8. 上传图片用PHP和击球脚本内存限制
- 9. PHP ini_set内存限制
- 10. PHP内存限制调试
- 11. Redis内存优化
- 12. 内存/ CPU优化?
- 13. python2.7内存限制版本
- 14. 可能优化Php脚本以限制对服务器内存和cpu的影响?
- 15. java opencv本地库和内存限制
- 16. PHP CLI脚本如何确定其内存限制?
- 17. Imagick内存和CPU限制
- 18. Action脚本和php中的代码优化运行时内存使用情况
- 19. PHP cli内存使用优化
- 20. PHP数组中的内存优化
- 21. Eclipse内存限制
- 22. iPad内存限制
- 23. .Net内存限制
- 24. .NET内存限制
- 25. MongoDB限制内存
- 26. Iphone限制内存
- 27. MIPS内存限制?
- 28. WordPress内存限制
- 29. EhCache内存限制
- 30. CUDA内存限制
如果您显示的代码,也许有人可以发现内存不是free'd。 'flush()'用于处理输出缓冲区。 – alex 2013-03-23 11:54:20
请注意PHP版本号。内存管理在PHP 5.2及更早版本中有很大不同。 – cleong 2013-03-23 11:55:44
我的问题与我的脚本无关。我只是想在概念上理解何时需要在代码中明确释放内存。 – CptNemo 2013-03-23 12:00:22