[PHP] 當你遇到memory size exhausted
之前寫了一段code,只要一跑,他就會出現以下的這一段
Fatal error: Allowed memory size of 268435456 bytes
exhausted (tried to allocate 36 bytes) in C:\xampp\htdocs\csv2array\csv2Array\csv2DiArray.php
on line 56
所以我就用 “memory size””PHP””exhausted”這些關鍵字去查,發現這問題還真的是經常出現呀。
出問題的地方在某個迴圈內,且這個迴圈是拿來操作array的。這個array也不過就是讀個400kb的csv檔,大約是10欄,4000筆的資料。
上stackoverflow,第一篇出現的解答,叫我們先去調整 php.ini的設定。在php.ini內有個記憶體上限。
memory_limit=256M
這一行,預設為128,可以改為256、512等。但我改完後,他只是不斷的在「1xxxxxxx bytes」變為「2xxxxxxxx bytes」直到「5xxxxxxx
bytes」為止。我稍微考慮了一下來源檔大小,記憶的限制應該不是原因。
這邊請注意一下,你會在文章中看到有些人會說,一開始下這一行,可以解決一部分人的問題
ini_set('memory_limit', '-1');
上面這一行的意思,就是不設限 memory,所以設定成「-1」。你可以把用盡所有主機的記憶體也沒關係。請注意,這是一個很危險的設定,因為他可能會在日後產生更大更大的問題。雖然這個答案很容易在stackoverflow被推上去,但仔細答案的reply的話,你會發現都會有人提出「這樣做很危險」。
後來再查了stackoverflow其他的文章,有個人遇到的是,他要寫入的array很大,也遇到了memory exhausted的問題。但他的問題在於array的等級把他的memory吃光了。
從這篇文章可以知道,每一個array的變數可能佔48 bytes 或 56 bytes,而那篇文章的array,應該是11欄,幾萬筆等級的來源。所以光是記憶體就耗了很多的部分在讀檔。
但,這也不是我這段code的問題,我的來源檔規模真的不大,儘10欄4000筆,連記算機都不用按,就知道他不會超過限制。
所以,接下來就是檢查code,我本來的想法是,這是一個二維array,我要遍歷所有的列,讀出[列數][p_code]這個的內容,如果他最後一碼不是T的話,就砍掉。Code如下。
for ($j =0 ; $j < $countArray; $j++)
{
$judge = $targetArray[$j][p_code];
$judge = substr($judge, -1);
//$judge = htmlentities($judge);
echo ($judge); // test of the judge ment
while ($judge != 'T')
$deleteKey [] = $j;
}
print_r ($deleteKey);
問題就在這段code,因為這段code出現了不會停的迴圈。改成下列,把$deleteKey[]拿掉,換成echo出所有非T結尾的元素。
for ($j =0 ; $j < $countArray; $j++)
{
$judge = $targetArray[$j][p_code];
$judge = substr($judge, -1);
//$judge = htmlentities($judge);
echo ($judge); // test of the judge ment
while ($judge != 'T')
echo ($targetArray[$j]['p_code']);
}
print_r ($deleteKey);
結果就是一切正常,這時候我再重新看網路上這些提問者的內容,除了來源array很大以外,很多出現這個fatal error的原因,就是他們設了迴圈,變數使用$key值找,又同時更改$key值。
最有效率的解法我並不知道,但我可能就會在其他的迴圈來處理 deleteKey這事情,所以第一個array就是單純抓出那些不含T結尾的key值,然後在loop 外使用另一個指令來deleteKey。
或許有更有效的方法吧,我稍微試了幾個foreach的指令,雖然還不確定怎麼寫會成功,但感覺如果用foreach來做,就可以做到了。
本人是個PHP新手,新到不能再新的新手,歡迎來信指導。
沒有留言:
張貼留言