關於PHP進程防止記憶體溢位的排查

2020-07-16 10:05:58

PHP進程記憶體大小是可以設定的,預設在組態檔 memory_limit=128M

也可以在程式中動態設定 ini_set('memory_limit', '1024M');這樣就設定成1G了。但是一般不會這樣設定,畢竟會影響到機器的其他服務。有時候可以排查一下程式碼,很多時候記憶體溢位是因為php變數沒有及時釋放,或者遍歷比較大的陣列時出現。

1.排查

memory_get_usage() php有這個系統函數,可以得到當前進程使用了多少記憶體空間。返回是位元組單位round(memory_get_usage()/1024/1024, 2).'MB',轉換為MB.

可以追蹤程式碼執行過程中記憶體的變化。

2.常見記憶體溢位的案例

遍歷大型陣列,修改陣列的某些值,導致遍歷過程陣列複製一份。

php變數的特點是「寫時複製」,

當涉及$arr陣列賦值時,會產生分裂,生成新的HashTable結構體,導致記憶體占用瞬間變大

3.遍歷賦值其他變數

$arr = range(0, 599999);
echo 'foreach前記憶體:'.round(memory_get_usage()/1024/1024, 2).'MB', '<br/>';
foreach($arr as $key => $item) {
    $arr[$key] = $item + 1;
    if($item % 100000 == 0) {
        echo 'foreach中記憶體:'.round(memory_get_usage()/1024/1024, 2).'MB', '<br/>';
    }
}
echo 'foreach後記憶體:'.round(memory_get_usage()/1024/1024, 2).'MB', '<br/>';

//輸出
/*
foreach前記憶體:49.9MB
foreach中記憶體:81.36MB
foreach中記憶體:84.42MB
foreach中記憶體:87.47MB
foreach中記憶體:90.52MB
foreach中記憶體:93.57MB
foreach中記憶體:96.62MB
foreach後記憶體:49.9MB
*/

解決方法,採用參照遍歷

$arr = range(0, 599999);
echo 'foreach前記憶體:'.round(memory_get_usage()/1024/1024, 2).'MB', '<br/>';

foreach($arr as $key => &$item) {
    $arr[$key] = $item + 1;
    if($item % 100000 == 0) {
        echo 'foreach中記憶體:'.round(memory_get_usage()/1024/1024, 2).'MB', '<br/>';
    }
}unset($key);unset($item);

遍歷完成後記得unset($key);unset($item); 因為$item是對陣列最後一個元素的參照,後面如果修改這個變數,會直接修改到陣列。

推薦:《PHP視訊教學

以上就是關於PHP進程防止記憶體溢位的排查的詳細內容,更多請關注TW511.COM其它相關文章!