PHP進程防止內測溢出的排查

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.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
*/

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/>';
    }
}unset($key);unset($item);

遍歷完成後記得unset($key);unset($item);  因爲$item是對數組最後一個元素的引用,後面如果修改這個變量,會直接修改到數組。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章