這可能更適合服務器故障,但我想我會在這裏先問一下。在內存不足錯誤後,PHP自動加載錯誤
我們有一個前置於我們服務器上每個PHP文件的文件,這個文件使用包含我們用於自動加載,環境檢測等的Bootstrap
類的自動預先安排。這一切都工作正常。
然而,當存在一個「內存不足」錯誤直接前面的(即,小於一個第二或甚至在相同的時間)到相同的服務器上的另一個文件的請求時,三種情況之一發生:
我們檢查
if(class_exists('Bootstrap')
,這是我們用來包裹類定義當我們第一次得到這個錯誤代碼,返回true
,這意味着階級已經儘管這是自動前置文件中聲明。我們從我們的自動預置文件中得到「無法重新聲明類Bootstrap」錯誤,這意味着
class_exists('Bootstrap')
返回false
,但它以某種方式仍然被聲明。- 該文件根本沒有被預置,導致依賴它的文件導致一次致命錯誤。
我們當然可以嘗試修復內存不足的問題,因爲這些問題似乎會導致其他錯誤,但由於各種原因,它們在我們的設置中不可修復或很難修復。但是,除此之外 - 在我看來,這是PHP中的一個錯誤,導致某些內存泄漏導致了auto-prepend指令的問題。
由於這種情況很少發生(這可能是我們的高流量服務器每週一次),所以這比任何事情都更加好奇。但我想知道 - 爲什麼會發生這種情況,我們該怎麼做才能解決這個問題?
我們使用PHP 5.4.19運行FreeBSD 9.2。
編輯:我們一直試圖在過去幾個月來解決這個發現有幾件事情:
這似乎只是我們的安全服務器上發生。內存不足問題主要集中在我們安全的服務器上(他們通常來自我們自己的員工試圖下載太多數據),所以這可能只是巧合,但值得指出
get_declared_classes
當我們遇到這個問題時,包含在觸發錯誤的頁面上沒有使用的類。例如,$_SERVER
的輸出表示此人在xyz.com上,但其中一個聲明的類僅用於abc.com,這是內存不足問題通常來自的地方。所有這些讓我相信PHP在得到內存不足錯誤之後沒有做正確的週期結束垃圾回收,這會導致
Bootstrap
類在下一頁的內存中完全或部分丟失如果在錯誤發生後足夠快,請求。我對PHP垃圾收集實際上不太熟悉,但我認爲這很可能是問題所在。
可能。聽起來像是一個堅硬的邊緣案件追捕。我會使用[dtrace](http://www.php.net/manual/en/features.dtrace.dtrace.php)來記錄(a)你的前置編譯,(b)GC在做什麼,以及(c)錯誤條件。對於GC位,您可能需要編寫自己的[靜態探針](http://blog.experimentalworks.net/2008/12/dtracing-php/)。另外,如果您正在運行APC,則會爲這些診斷程序禁用它。 – bishop
謝謝。現在出現這樣一個難題:讓我們自己相信這是一個足夠大的問題,需要深入解釋器和gc才能解決。 :-D – jraede
您在那些服務器上使用任何類型的操作碼緩存嗎?你使用PHP作爲模塊還是(快)CGI?你的_server_內存不足,還是隻是達到極限的php腳本? – Wrikken