關於 insufficient memory case 4 的解決記錄



用戶在上傳圖片的時候,系統會報異常 insufficient memory case 4,追蹤代碼發生在jdk中 image.io 的 read() 方法。這是一個耽擱了很久的bug,客戶反饋了好幾次,找了幾次方向都沒處理好,搞得客戶很不耐煩,我自己也很傷腦筋,差點就投降了。

我嘗試過本地測試復現,但是也只是在多線程同時並發才會出現,線上出現該異常的時候,只有一個人在使用,所以當時也是很疑惑。對於內存不足來說,這個和內存溢出OutOfMemoryError是不一樣的,后者往往是分配給JVM的內存不足,前者實際上可能更多是物理本地內存不足(當然,這是后來才知道的)

在找尋解決方案的過程中,看到了 github 上的一個issue: Exception generating thumbnail image: Insufficient memory (case 4) 

其中有段回復是這樣說明的:“ Summing it up, I'm going to guess that the situation is that the JVM has enough memory allocated to it by the OS, but the JPEG decoder which is (probably) calling native code of libjpeg, and libjpeg is unable to obtain more free memory from the OS. You may want to look at how much (virtual) memory that the OS has free at the time you encounter this error. If my guess is correct, it would mean that you'll need to reduce the amount of parallel processing, and adding more heap (-Xmx) to the JVM probably isn't going to alleviate the situation.

可以看到,他說可能的原因在於JVM的內存是足夠的,但是在調用一些其他非Java代碼的接口,即native方法時,這些方法無法從系統中獲取到足夠使用的物理內存,於是造成了該異常。方向有了,看看服務器整體物理內存的使用情況。

於是我在客戶告知我異常時,登陸服務器查看了內存的使用,服務器是8G內存,當時顯示已使用內存高達7.9G(吃驚,怎么這么高),其中有個進程占用高達5G以上,是誰呢?sqlserver.exe(當時就驚了)

這是因為sqlserver.exe默認使用的策略是用多少內存占多少內存,只有服務器內存不足才會釋放一些。這些內存多用來進行 “查詢出的數據緩存” 和 “執行命令緩存”,所以解決方法其實很簡單,調整sqlserver的可使用物理內存即可(圖來自網絡):

我把sqlserver的內存使用限制在了3G,之后問題便迎刃而解。那句話怎么說來着,改代碼兩分鍾,DEBUG兩小時,說得真沒錯,關鍵是我DEBUG了好幾天   : )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM