在調試耗盡內存的代碼時,我發現了一個非常有趣的問題,最重要的是我不知道如何解決這個問題。通過引用自身破壞對象
該應用程序大致由單個Survey
對象組成,其中包含多個Question
對象。 Question對象包含對他們所在調查的引用,例如,需要從其他問題獲取答案。
下面的循環是造成內存溢出:
foreach ($survey_ids_arr as $survey_id) {
$Survey = new Survey($survey_id);
}
真的沒什麼異國情調的調查構造正在發生的事情;
- 從數據庫
- 從數據庫
- 獲取的所有問題的屬性創建每一個問題一個問題對象獲取其屬性(傳遞一個參考$這個)
- 將所有問題對象的內部陣列
並且從查看代碼,您會說在每次迭代中,由於$ Survey變量被覆蓋,所以對象從內存中清除。對??錯誤:)
隨着腳本經過循環,內存堆積 - 調用顯示調查對象使用的內存未按預期釋放,此時另一個對象被分配給$Survey
變量。即使在循環結束時調用unset($Survey)
也不會釋放內存。
罪魁禍首是傳遞給在創建問題的對象$this
引用。這些引用防止對象從內存中清除 - 作爲php.net狀態手冊:
析構函數方法將被調用,一旦到某個對象的所有引用都被刪除
所以什麼阻止對象被清理,是它對自身的引用。很好,嗯? :)
所以,問題是我的對象是一個記憶殺手。不幸的是,我想不出一個解決方案(除了寫一個醜陋的方法來清除問題並從循環中調用它)。 Survey中的析構函數不是一個選項;如上所述,這不叫,因爲 Question對象仍然有引用。
任何想法?有人必須已經遇到了這個問題 - 含父項的子對象並不是一個不常見的體系結構,是嗎?
問題是你的設計中存在一個矛盾:你想阻止對象從內存中清除,但你想清除它? – m0skit0
在php 5.3中解決了這個問題。你使用什麼PHP版本? – J0HN
你是對的J0HN,我剛剛發現了錯誤報告! https://bugs.php.net/bug.php?id=33595 – Rijk