【发布时间】:2010-02-19 16:34:11
【问题描述】:
我们最近将一些应用程序从在 RedHat linux JDK1.6.0_03 下运行的迁移到 Solaris 10u8 JDK1.6.0_16(更高规格的机器),我们注意到一个似乎相当紧迫的问题:在某些负载下我们的 JVM 让自己陷入“死亡螺旋”并最终耗尽内存。注意事项:
- 这不是内存泄漏的情况。这些应用程序运行良好(在一种情况下运行了 3 年以上),内存不足错误在任何情况下都不确定。应用程序有时工作,有时不工作
- 这不是我们迁移到 64 位 VM - 我们仍在运行 32 位
- 在一种情况下,在 1.6.0_18 上使用最新的 G1 垃圾收集器似乎已经解决了问题。另一方面,回到 1.6.0_03 已经奏效
- 有时我们的应用程序会因 HotSpot
SIGSEGV错误而崩溃 - 这会影响用 Java 和 Scala 编写的应用程序
最重要的一点是:这种行为表现在那些突然获得大量数据(通常通过 TCP)的应用程序中。就好像 VM 决定继续添加更多数据(可能会将其推进到 TG),而不是在“新空间”上运行 GC,直到它意识到它必须执行完整的 GC,然后,尽管几乎所有内容都在VM 是垃圾,它以某种方式决定不收集它!
这听起来很疯狂,但我只是看不出还有什么。你怎么能解释一个应用程序,它一分钟崩溃,最大堆为 1Gb,下一分钟工作正常(当应用程序执行完全相同的事情时,永远不会达到大约 256M)
所以我的问题是:
- 有其他人观察到这种行为吗?
- 对我如何调试 JVM 本身(而不是我的应用程序)有任何建议吗?如何证明这是 VM 问题?
- 是否有任何 VM 专家论坛,我可以在其中询问 VM 的作者(假设他们不在 SO 上)? (我们没有支持合同)
- 如果这是最新版本的 VM 中的错误,为什么没有其他人注意到它?
【问题讨论】:
-
假设您可以重现问题:(1)创建导致失败的最小测试用例; (2)在另一个JVM下运行测试用例(openjdk.java.net); (3) 将测试用例发送给 Sun/Oracle。 JVM 不应违反段。
-
是的 - 我可以想象它需要很长时间才能复制。我的意思是他们必须对这些东西进行测试,对吧?
-
我有一个类似的问题:它也只发生在向应用程序提供大量数据时,但它总是触发一个 SIGSEGV,我不知道该怎么处理它,所以我提出了一个新问题:stackoverflow.com/questions/2299250/… 我的解决方法是同时使用 1.5 JVM。
标签: java scala jvm solaris out-of-memory