我有一個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. Magento - PHP腳本內存限制過載
- 2. PHP內存優化
- 3. PHP腳本內存優化 - 需要降低運行腳本
- 4. 優化內存密集型腳本
- 5. PHP - 內存限制
- 6. PHP內存限制
- 7. PHP內存限制
- 8. PHP內存限制
- 9. PHP內存限制
- 10. 上傳圖片用PHP和擊球腳本內存限制
- 11. 爲PHP和MySQL優化內存管理
- 12. PHP內存限制錯誤?
- 13. PHP內存限制測試
- 14. PHP ini_set內存限制
- 15. PHP內存限制調試
- 16. PHP PDO內存限制
- 17. 內存/ CPU優化?
- 18. Lua優化內存
- 19. Redis內存優化
- 20. 內存不足 - 內存優化
- 21. python2.7內存限制版本
- 22. Php腳本內存不足
- 23. 可能優化Php腳本以限制對服務器內存和cpu的影響?
- 24. java opencv本地庫和內存限制
- 25. Imagick內存和CPU限制
- 26. MemoryCache absoluteExpiration和內存限制
- 27. 執行PHP腳本時達到的內存限制
- 28. PHP CLI腳本如何確定其內存限制?
- 29. OpenHFT ChronicleMap內存的限制和限制
- 30. Action腳本和php中的代碼優化運行時內存使用情況
如果您顯示的代碼,也許有人可以發現內存不是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