php為什麼運行了一段時間後才報內存溢出?

WBOY
發布: 2023-03-02 07:02:01
原創
1557 人瀏覽過

我一次從資料庫讀取了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是動態語言,記憶體管理操作是隱藏的,你用同一個變數看似用同一個記憶體區域,但事情上並不是。

相關標籤:
php
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!