php記憶體機制
Php記憶體管理機制
PHP不需要顯式的對記憶體進行管理,這些工作都由PHP直譯器進行了。由此PHP內部有一個記憶體管理體系, 它會自動將不再使用的記憶體垃圾進行釋放,php的預設記憶體大小是32M,在php.ini中memory_limit = 32M
- memory_get_usage(),這個函式的作用是獲取 目前PHP指令碼所用的記憶體大小。
- memory_get_peak_usage(),這個函式的作用返回 當前指令碼到目前位置所佔用的記憶體峰值,這樣就可能獲取到目前的指令碼的記憶體需求情況。
從開始就有一套屬於自己的記憶體管理機制,在5.3之前使用的是經典的引用計數技術,但引用技術存在一定的技術缺陷,在PHP5.3之後,引入了新的垃圾回收機制,至此,PHP的記憶體管理機制更加完善。
一次性讀取超大的檔案到記憶體中,或者出現超大的陣列,或者在大迴圈中的沒有及時是放掉不再使用的變數, 這些都有可能會造成記憶體佔用過大而被終止
Fatal error:Allowed memory size of X bytes exhausted (tried to allocate Y bytes)
記憶體管理一般會包括以下內容:
- 是否有足夠的記憶體供我們的程式使用;
- 如何從足夠可用的記憶體中獲取部分記憶體;
- 對於使用後的記憶體,是否可以將其銷燬並將其重新分配給其它程式使用。
PHP底層對記憶體的管理, 圍繞著小塊記憶體列表(free_buckets)、 大塊記憶體列表(large_free_buckets)和剩餘記憶體列表(rest_buckets)三個列表來分層進行的。 ZendMM向系統進行的記憶體申請,並不是有需要時向系統即時申請,而是由ZendMM的最底層(heap層)先向系統申請一大塊的記憶體,通過對上面三種列表的填充,建立一個類似於記憶體池的管理機制。 在程式執行需要使用記憶體的時候,ZendMM會在記憶體池中分配相應的記憶體供使用。這樣做的好處是避免了PHP向系統頻繁的記憶體申請操作
PHP對記憶體的分配,是結合PHP的用途來設計的,PHP一般用於web應用程式的資料支援,單個指令碼的執行週期一般比較短(最多達到秒級),記憶體大塊整塊的申請,自主進行小塊的分配, 沒有進行比較複雜的不相臨地址的空閒記憶體合併,而是集中再次向系統請求。 這樣做的好處就是執行速度會更快,缺點是隨著程式的執行時間的變長,記憶體的使用情況會“越來越多”(PHP5.2及更早版本)。 所以PHP5.3之前的版本並不適合做為守護程序長期執行。
銷燬
ZendMM在記憶體銷燬的處理上採用與記憶體申請相同的策略,當程式unset一個變數或者是其他的釋放行為時, ZendMM並不會直接立刻將記憶體交回給系統,而是隻在自身維護的記憶體池中將其重新標識為可用,按照記憶體的大小整理到上面所說的三種列表(small,large,free)之中,以備下次記憶體申請時使用。