2013-07-25 72 views
7

我有一個Java應用程序部署在運行在Ubuntu 10.04上的Tomcat 7上。還有的是開放的服務器套接字期間的問題,我不能到目前爲止重現:java.net.SocketException:無法分配內存(不是Mac)

java.net.SocketException: Cannot allocate memory 
at java.net.PlainSocketImpl.socketBind(Native Method) 
at java.net.AbstractPlainSocketImpl.bind(Unknown Source) 
at java.net.ServerSocket.bind(Unknown Source) 
at org.subethamail.smtp.server.SMTPServer.createServerSocket(SMTPServer.java:338) 
at org.subethamail.smtp.server.SMTPServer.start(SMTPServer.java:291) 

所有我已經能夠找出的是,這種情況在Mac OS的一些具體的版本,這是不相關的我,也在OpenJDK上,這也是不相關的(我正在使用Oracle JRE 1.7.0_17)。另一個可能的原因是虛擬化環境,但在我的情況下,這發生在硬件盒上。

所以,問題是,有沒有人遇到同樣的問題,可能有什麼解決方案。

更新 還有一件事:tomcat幾乎消耗了所有的堆,大約700mb,它是由我的代碼中的內存泄漏引起的。 但據我所知,異常告訴系統級別的套接字緩衝區,所以它似乎沒有與java堆相關。然而,這是我迄今爲止唯一的解釋,我認爲這是非常虛幻的。

更新2 最終我們已經能夠重現該問題幾次,所以這不是內存泄漏。當我第一次面對這個問題時,我正在考慮將authbind作爲問題的一個可能的來源,但不幸的是我沒有太注意它。當我遇到另一個受此問題影響的硬件盒時,我嘗試綁定未授權的端口併成功,而嘗試綁定已授權的端口則導致異常。所以,最終我用iptables取代了authbind。

基本上,忌諱塔希爾的回答點authbind,但丹尼·托馬斯的回答提供有關分叉和「無法分配內存」之間的連接非常interresting信息, 其實我們還可以使用進程生成器運行的bash腳本,所以有很大的機會問題可能是由它引起的。

+0

它是一個32位或64位JDK? – fge

+0

這是一個32位jre(不是jdk,我的錯) –

+0

你有沒有試過64位JRE或JDK代替N – fge

回答

4

聽起來就像你沒有足夠的物理內存或交換 - 在系統上影響檢查內存並交換。

您的應用程序是否執行外部命令 - fork/exec可能會起作用。你可能會考慮允許內存過量使用,如果是這樣的話:

http://bryanmarty.com/blog/2012/01/14/forking-jvm/

+0

謝謝,丹尼托馬斯。事實證明,我們正在使用的authbind也在執行fork()。在內存使用高峯期重新綁定可能導致上述錯誤,雖然堆還沒有完全耗盡。所以我們擺脫了authbind,問題就解決了。 – Jk1

+0

啊,太棒了。很高興我能幫上忙! –

0
  • 您可以擴展Java的堆空間進行檢查。
  • 如果您正在開發的項目是由另一個java版本創建的,則可能會發生該問題。
1

也請檢查以下項目:

  • 運行內存測試,以消除對swap分區故障內存模塊
  • 運行磁盤檢查
  • 檢查(相當於其在Mac OS中)用戶資源限制(ulimit
+0

感謝您的回覆。在多個硬件安裝(至少10個)上觀察到此問題,所以我懷疑他們所有的內存或光盤損壞 – Jk1

+0

@ JK1:你會驚訝於你可能遇到的各種硬件故障巧合... – carlspring

0

儘量減少分配到Tomcat的存儲器(catalina.sh的-Xmx參數)。同時增加tomcat的最大堆大小。如果它不能解決它,你必須在代碼中找到內存泄漏,其中一個工具是java melody,使用它並找到內存泄漏來解決問題。