2013-04-20 64 views
-8

我有一個服務器,通過套接字處理請求,併產生一個線程來處理每個請求。爲什麼我會得到java.lang.OutOfMemory錯誤?

爲什麼我得到java.lang.OutOfMemoryError,我該怎麼辦才能修復它?

+3

也許是在33-40行,你創建一個大小爲2 ** 29的字節數組,並把它添加到一個ArrayList 無限循環。 – 2013-04-20 02:43:38

+0

https://www.google.co.in/search?q=reasons+for+java+outofmemoryexception+&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a – Jayan 2013-04-20 02:45:13

+1

請確保如果你回答自己的問題,這個問題是適合獨立的。原來,這個問題屬於「不是真正的問題」。 – Zyerah 2013-04-20 02:49:32

回答

2

類型I:超出堆空間。

這是最常見的錯誤。追查可能很難,因爲它涉及瞭解什麼物體是「正常」的,哪些物體應該被釋放。

創建無限量的引用對象。創建特定於線程的對象,但會被另一個全局對象引用。

如果你能重現該問題,運行jmap -dump:format=b,file=output.bin

然後分析了堆文件,jhat

II型:進程的內存

的。如果你已經實現了JNI調用,或對代表您的JVM,這 創建JNI對象創建的對象,你可以運行進程的內存,這對於32位進程是4演出。

正在運行的Java進程的進程空間包括:

  • JVM內存
  • 加載庫
  • 本地創建的對象

-Xmx只能控制JVM的大小記憶。

III型:垃圾收集不運行

我還沒有發現這種情況在任何網絡搜索的任何引用。我想我已閱讀每個帖子來解決​​。

如果您有一個Java程序正在對本地代碼進行JNI調用,那麼當任何線程處於JNI調用時,垃圾收集器不會運行。給定一個足夠繁忙的系統,在JNI調用中有兩個或多個線程,這可能導致垃圾收集器無法運行。

第一個實例是一個長時間運行的JNI調用,它將回調到java代碼中以釋放當前對象並獲取新對象。在每次迭代中,使用的內存量增加,未使用的對象不會被垃圾收集。

第二個實例是一個測試,其中每個派生線程都會導致JNI調用。該代碼會運行很長時間,大約一個小時左右,但會死亡java.lang.OutOfMemoryError-Xloggc選項在前4000秒內顯示定期垃圾回收,直到正在運行的併發線程數增加爲止。

4055.330: [GC 4055.330: [ParNew: 147424K->12220K(147456K), 0.0073372 secs] 769563K->637289K(1294336K) icms_dc=0 , 0.0073809 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
18668.710: [GC 18668.710: [ParNew: 143289K->16384K(147456K), 0.0297121 secs] 768358K->651851K(1294336K) icms_dc=0 , 0.0297604 secs] 

[更新2014年6月7日] 在一種情況下,我發現這個答案Memory leak when calling java code from C using JNI固定的問題。 本地java內存被分配給C棧,即使它是在java中分配的,因爲它是在JNI調用中完成的。具體來說,我使用PushLocalFrame()/ PopLocalFrame()將回調函數包裝爲java來解決問題。