我一次從資料庫讀取了10萬條數據,然後循環做一些計算,循環過程中,涉及到的變數都會被下次循環覆蓋掉,現在的情況是程式運行了一段時間之後,報內存溢出,為什麼不是剛開始的時候就報內存溢出?依照我的理解,我並沒有用變數一直去存運算結果,所以如果說記憶體溢出的話,應該就在一開始就報了啊。
我一次從資料庫讀取了10萬條數據,然後循環做一些計算,循環過程中,涉及到的變數都會被下次循環覆蓋掉,現在的情況是程式運行了一段時間之後,報內存溢出,為什麼不是剛開始的時候就報內存溢出?依照我的理解,我並沒有用變數一直去存運算結果,所以如果說記憶體溢出的話,應該就在一開始就報了啊。
php version 5.5+
循環中使用yield關鍵字,迭代中的中間變數可以不佔用額外的記憶體空間
例:
<code>for($i = 1; $i <= 10; $i += 1) yield $i;</code>
在php中其實變數都是透過zval變數來保存,zend_uint refcount__gc 是該變數中的一個計數器,用來保存有多少變數。在變數生成時,其refcount=1,典型的賦值運算如$a = $b會令zval的refcount加1,而unset操作會對應的減1。在PHP5.3之前,使用引用計數的機制來實作GC,如果一個zval的refcount較少到0,那麼Zend引擎會認為沒有任何變數指向該zval,因此會釋放該zval所佔的記憶體空間。但,事情有時並不會那麼簡單。後面我們會看到,單純的引用計數機制無法GC掉循環引用的zval,即使指向該zval的變數已經被unset,導致了記憶體外洩。
你在循環覆蓋變數的時候,其實本質的recount值並沒有減少,所以所佔用記憶體並沒有釋放,最後一定會爆炸。
解決方案:
<code>ini_set(‘memory_limit’,’1024M’); </code>
問題分析:
<code>=。=没代码怎么分析。。。 </code>
可能原因:
<code>读取数据不要时间啊? 变量覆盖之前生成的临时对象就不占内存啊?</code>
你從資料庫讀取10w筆資料的時候,估計就已經記憶體不足了吧
我印像中變數重新賦值,記憶體中的物件資料其實會COPY一份,用unset或GC才會釋放,不過我找不到相關資料。
記憶體佔用因素很多,PHP是動態語言,記憶體管理操作是隱藏的,你用同一個變數看似用同一個記憶體區域,但事情上並不是。