8

我在 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 作为问题的可能根源,但不幸的是我并没有太多关注它。当我遇到另一个受问题影响的硬件盒时,我尝试绑定非特权端口并成功,而尝试绑定特权端口会导致异常。所以,最终我用 iptables 替换了 authbind。

基本上,fady taher 的回答指向 authbind,但 Danny Thomas 的回答提供了有关分叉和“无法分配内存”之间连接的非常有趣的信息,实际上我们也使用进程构建器来运行 bash 脚本,所以问题很可能是由它引起的。

4

5 回答 5

4

听起来您的物理内存或交换不足 - 在受影响的系统上,检查内存和交换。

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

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

于 2013-09-25T10:27:35.740 回答
1

还请检查以下项目:

  • 运行内存测试以消除坏内存块
  • 在交换分区上运行磁盘检查(相当于 Mac OS 上的)
  • 检查用户资源限制 ( ulimit)
于 2013-09-25T09:39:19.453 回答
0

不知道是否有帮助,但请检查

尝试将 Apache Tomcat 端口从 8080 更改为 80 时出现内存错误

于 2013-09-24T13:50:39.327 回答
0
  • 您可以为它扩展 Java 堆空间检查。
  • 如果您正在开发的项目是由另一个 java 版本创建的,则可能会发生该问题。
于 2013-09-25T09:20:25.667 回答
0

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

于 2013-09-30T09:47:36.010 回答