首頁 > 網際網路

如何解決 PHP Fatal error: Allowed memory of

2019-12-14 02:32:28

在匯出訂單資料的時候,當訂單量達到13849的時候,頁面就直接返回:500了。檢視nginx紀錄檔,錯誤資訊如下:


1

從nginx紀錄檔中可知,是記憶體不夠用了,預設一個php進程允許佔用的記憶體是134217728bytes,而這個php進程還需要1048560bytes記憶體才能往下執行。

在php.ini中有關於記憶體的限制:

memory_limit = 128M  //128M=131072K=134217728b

我可以把這個值改的大一點來解決問題。


2

但為什麼才1萬多資料就佔去了128M的記憶體那?

於是用 echo__LINE__.":".memory_get_usage(),"<br>";

逐行看程式記憶體占用,以此來優化記憶體


1

去掉多餘函數和變數

程式碼中的空格和註釋都不影響記憶體的占用,但呼叫檔案中多餘的函數和變數就會佔用記憶體,於是把不用的函數方法和變數刪除掉,尤其是一些複製過來的檔案,會有很多不需要的方法,一定要刪掉


2

不要宣告多餘的變數

如:


3

不用的變數及時釋放掉

有些變數都是過程變數,尤其是做一些資料格式化轉換的時候,一些原始的,過度的變數要及時釋放掉

如:


4

優化函數返回結果大小

函數盡可能的只返回每次呼叫所需要的結果集

比如:要得到的是:$datastruct


5

優化mysql返回結果集的大小(效果顯著)

查詢了一下表中資料的大小 (看圖)

大小:2.52MB.

再看看結果集在PHP中佔的記憶體:

記憶體耗用:(76201912-1086264)/1024/1024 = 71.64M

哇 PHP的陣列太佔記憶體了

網上有人做過陣列佔用記憶體的測試,如下:



6

PHP中的陣列是用一種HASH結構(HashTable)來實現的,

關於PHP中的陣列的實現,鳥哥有一篇文章介紹過:深入理解PHP之陣列(遍歷順序)

那麼我們怎麼優化那?

1:縮小返回的結果集,一開始是查詢出了所有欄位,改成 只返回需要的欄位

2:在1的基礎上,我們再使用 mysql_unbuffered_query來查詢資料


7

快取裡盡量只存需要的資訊

目前我們常用redis memcache做快取,如果存全量資訊,隨著資料量的增加,全量資訊會成倍數的增加,都很消耗機器記憶體


8

設計資料庫的時候,把資料庫欄位設計的盡可能小(前提是滿足需求)

1:為了省空間 2:為了查詢的時候


9

這樣基本就搞定了。

推薦以下鳥哥的三篇文章:(http://www.laruence.com/)

 深入理解PHP記憶體管理之誰動了我的記憶體

 深入理解PHP之陣列(遍歷順序)

 PHP中的Hash演算法



IT145.com E-mail:sddin#qq.com