java.net.SocketException:无法分配内存(不是Mac)

时间:2013-07-25 09:05:18

标签: java tomcat ubuntu

我在ubuntu 10.04上运行的tomcat 7上部署了一个java应用程序。在打开服务器套接字时出现了一个问题,到目前为止我无法重现:

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)

所有我能够发现的是,这种情况发生在MacOS的某些特定版本上,这与我无关,也与OpenJDK无关,这也与我不相关(我使用的是Oracle JRE) 1.7.0_17)。另一个可能的原因是虚拟化环境,但在我的情况下,这发生在硬件盒上。

所以,问题是,是否有人遇到过同样的问题以及可能的解决方案。

更新 还有这样的事情:tomcat消耗了几乎所有的堆,大约700mb,它是由我的代码中的内存泄漏造成的。 但据我所知,异常讲述了系统级别的套接字缓冲区,因此它似乎与java堆无关。然而,这是我到目前为止唯一的解释,在我看来这是非常虚幻的。

更新2 最终,我们已经能够多次重现该问题,因此这不是关于内存泄漏的问题。当我第一次面对这个问题时,我正在考虑将authbind作为问题的可能来源,但不幸的是我并没有太多关注它。当我得到另一个受此问题影响的硬件盒时,我尝试绑定非priveleged端口并成功,而尝试绑定priveleged端口会导致异常。所以,最终我用iptables取代了authbind。

基本上,fady taher的答案指向authbind,但Danny Thomas的回答提供了关于分叉和"无法分配内存的关联的非常有趣的信息", 实际上我们也使用流程构建器来运行bash脚本,因此很可能会出现问题。

5 个答案:

答案 0 :(得分:4)

听起来你没有足够的物理内存或交换 - 受影响的系统,检查内存和交换。

您的应用程序是否恰好执行外部命令 - fork / exec可能有所贡献。如果是这种情况,您可以考虑允许内存过量使用:

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

答案 1 :(得分:1)

请同时检查以下项目:

  • 运行内存测试以消除坏内存块
  • 在交换分区上运行磁盘检查(在Mac OS上相当于)
  • 检查用户资源限制(ulimit

答案 2 :(得分:0)

答案 3 :(得分:0)

  • 您可以为它扩展java堆空间检查。
  • 如果您正在开发的项目是由另一个Java版本创建的,则可能会出现该问题。

答案 4 :(得分:0)

尝试减少分配给Tomcat的内存(catalina.sh中的-Xmx参数)。还增加了tomcat的最大堆大小。如果它没有解决它,你必须在代码中找到内存泄漏,一个这样的工具是java melody,使用它并找到内存泄漏来解决问题。