【问题标题】:Java crashed application - how to find out why Java crashed?Java 崩溃的应用程序 - 如何找出 Java 崩溃的原因?
【发布时间】:2011-02-15 12:27:04
【问题描述】:

我的 java 服务器开始反复崩溃,我找不到原因。

我有 7.5GB 内存的服务器,我为 java 进程分配了 3GB。

服务器运行良好,多次运行垃圾回收,但 JVM 在内存压力下崩溃。

这是崩溃后来自 JConsole 的信息:

Current heap size: 
2 958 868 kbytes
Maximum heap size: 
3 066 816 kbytes
Committed memory: 
3 066 816 kbytes
Pending finalization: 
0 objects
Garbage collector: 
Name = 'PS MarkSweep', Collections = 66, Total time spent = 7 minutes
Garbage collector: 
Name = 'PS Scavenge', Collections = 43 055, Total time spent = 44 minutes



Operating System: 
Linux 2.6.31-302-ec2
Architecture: 
amd64
Number of processors: 
2
Committed virtual memory: 
8 405 760 kbytes
Total physical memory: 
7 882 780 kbytes
Free physical memory: 
   34 540 kbytes
Total swap space: 
        0 kbytes
Free swap space: 
        0 kbytes

在 GC 运行后我有 0.5 GB,所以它一直从 0.5 增加到 3 GB,而不是回落到 0.5,悬挂对象绝对没有问题。事实上,它应该抛出 OutOfMemoryException 而不是崩溃。我正在使用这些参数:

-Xmn256m -Xms768m -Xmx3000m -XX:NewRatio=2 -server -verbosegc -XX:PermSize=256m -XX:MaxPermSize=256m -XX:SurvivorRatio=8 -XX:+UseParallelGC -XX:ParallelGCThreads=2 -XX:+UseParallelOldGC

出了什么问题,我该怎么办?显示的输出是:

Current thread (0x00007fe899755800):  JavaThread "508616253@qtp-1871151428-3352" [_thread_in_vm, id=11941, stack(0x00007fe86a4e5000,0x00007fe86a5e6000)]

siginfo:si_signo=SIGSEGV: si_errno=0, si_code=128 (), si_addr=0x0000000000000000

Registers:
RAX=0x00007fe9c60333b8, RBX=0x00007fe899755800, RCX=0x0d00007fe8f58787, RDX=0x00007fe9c6031888
RSP=0x00007fe86a5e3fd0, RBP=0x00007fe86a5e4020, RSI=0x00007fe899755800, RDI=0x00007fe95bae1770
R8 =0x00007fe9be341620, R9 =0x0000000000000001, R10=0x00007fe9c5b84460, R11=0x00007fe9c051a52b
R12=0x00007fe9c051a529, R13=0x00007fe9c6034ac0, R14=0x00007fe9c051a599, R15=0x0900007fe8f58787
RIP=0x00007fe9c5bd562d, EFL=0x0000000000010246, CSGSFS=0x000000000000e033, ERR=0x0000000000000000
  TRAPNO=0x000000000000000d

Stack: [0x00007fe86a4e5000,0x00007fe86a5e6000],  sp=0x00007fe86a5e3fd0,  free space=3fb0000000000000030k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x64d62d]
V  [libjvm.so+0x5fc4df]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
v  ~RuntimeStub::_complete_monitor_locking_Java
J  sun.nio.ch.SocketChannelImpl.write(Ljava/nio/ByteBuffer;)I
J  org.mortbay.io.nio.ChannelEndPoint.flush(Lorg/mortbay/io/Buffer;)I
J  org.mortbay.jetty.HttpGenerator.flush()J
...

【问题讨论】:

  • 有没有JNI组件?
  • 你多次“做”GC这一事实应该敲响警钟。如果您不执行任何 GC 并依靠 JVM 以它认为最好的方式执行它,那么服务器的行为是什么?
  • 正在运行哪些程序? Java 自己执行垃圾收集,但如果程序发生内存泄漏,这可能还不够。
  • 不,没有使用 JNI。
  • 服务器负载过重,大量连接用户在线,那些经常调用的垃圾收集是我自己配置​​的快速垃圾收集算法,有助于防止在进行常规 GB 收集时发生时间泄漏。

标签: java crash jvm out-of-memory jvm-crash


【解决方案1】:

从您链接的崩溃文档中,错误是 SIGSEGV,它是读取/写入本机内存的错误。线程堆栈显示它在 JVM 代码中崩溃。

Current thread (0x00007fe899755800):  JavaThread "508616253@qtp-1871151428-3352" [_thread_in_vm, id=11941, stack(0x00007fe86a4e5000,0x00007fe86a5e6000)]

siginfo:si_signo=SIGSEGV: si_errno=0, si_code=128 (), si_addr=0x0000000000000000

Registers:
RAX=0x00007fe9c60333b8, RBX=0x00007fe899755800, RCX=0x0d00007fe8f58787, RDX=0x00007fe9c6031888
RSP=0x00007fe86a5e3fd0, RBP=0x00007fe86a5e4020, RSI=0x00007fe899755800, RDI=0x00007fe95bae1770
R8 =0x00007fe9be341620, R9 =0x0000000000000001, R10=0x00007fe9c5b84460, R11=0x00007fe9c051a52b
R12=0x00007fe9c051a529, R13=0x00007fe9c6034ac0, R14=0x00007fe9c051a599, R15=0x0900007fe8f58787
RIP=0x00007fe9c5bd562d, EFL=0x0000000000010246, CSGSFS=0x000000000000e033, ERR=0x0000000000000000
  TRAPNO=0x000000000000000d

Stack: [0x00007fe86a4e5000,0x00007fe86a5e6000],  sp=0x00007fe86a5e3fd0,  free space=3fb0000000000000030k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x64d62d]
V  [libjvm.so+0x5fc4df]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
v  ~RuntimeStub::_complete_monitor_locking_Java
J  sun.nio.ch.SocketChannelImpl.write(Ljava/nio/ByteBuffer;)I
J  org.mortbay.io.nio.ChannelEndPoint.flush(Lorg/mortbay/io/Buffer;)I
J  org.mortbay.jetty.HttpGenerator.flush()J
<snip>

可能是 JVM 错误,也可能是内存损坏。

【讨论】:

    【解决方案2】:

    如果你有“内存问题”意味着你担心你的物理硬件有缺陷,你应该强烈考虑对它进行压力测试。

    对于传统 PC 而言,执行此操作的常用方法是使用 memtest86。最新版本似乎可以从这里获得:http://www.memtest.org/

    如果内存通过 memtest86 的通宵测试,您可以确定它可以正常工作。

    【讨论】:

    • 我正在使用亚马逊服务器,新机 1 天,由于旧虚拟机有缺陷,我希望新机能有所帮助。绝对不是硬件问题。如果不是java的问题,只能是linux的问题。
    • 好的,那就澄清了。查看 JDK 中的 jvisualvm - 它允许您分析正在运行的应用程序 - 您需要查找内存泄漏。
    【解决方案3】:

    当您说您为 JVM 分配了 3 GB 时,这是堆大小还是总大小(可能更大一些),例如具有 3 GB 堆的 JVM 总共可以使用 clsoe 到 4 GB。

    如果 JVM 在 GC 上崩溃,我会检查您是否有当前版本的 JVM,例如 Java 6 update 23。

    什么是崩溃?有时,其他人也报告了同样的崩溃,你可以用谷歌搜索它。有时会有建议的解决方案。

    【讨论】:

    • 我只分配了 3GB,另外还有 4.5Gb 可以免费使用,所以我总共有 7.5GB。它是免费的内存,没有其他大型进程在 linux 上运行。
    • 我也用过 JAVA 5,JAVA 6 最新的,OpenJDK 最新的,总是一样的结果。并且 JVM 生成了崩溃文件,不是每次都生成,但有时会生成。你可以在这里找到崩溃文件的例子:chessfriends-release.s3.amazonaws.com/logs/…
    • 我发现 Java 6 update 18 很稳定。但它仍然值得尝试使用更新的 JVM 的更新 23 或 24。 (超过一年 AFAIK)
    • 我也用了6.23,结果一样。
    • 我可以建议的唯一简单的事情是尝试 32 位版本(尽管这可能没有足够的内存)它看起来像一个 JVM/本机错误给我。接下来你可以尝试 Ubuntu 10.x :|
    【解决方案4】:

    听起来像是内存泄漏。 gc 只能清理不再引用的对象。而且,如果您的应用程序(或服务器本身)没有“释放”未使用的资源,那么一段时间后,即使 3GB 也不够。

    Profiler 可能有助于识别意外增长的数据结构。


    想法:使用-verbose:gc 选项启动服务器并检查在它死前会发生什么。减少测试的堆空间,这样您就不必等待很长时间。如果这是内存泄漏,我希望您会看到常规的完整 gc 循环,其中 gc 每次运行时可以释放更少的内存。


    更新

    我被outofmemoryerror 标签误导了。实际上,这是 JVM 崩溃,您所能做的就是尝试更新已安装的 Java。已经有一些关于构建 1.6.0_17 和 1.6.0_18 (like this question on SO) 的“SIGSEGV (0xb)”崩溃的报告。

    这是 JVM 内部问题。

    【讨论】:

    • 然后切换到jmap和jhat帮助诊断泄漏。
    • 不,是要清理的垃圾。 GB运行后我一直有0,5 GB,所以它一直从0,5上升到3 GB然后回落到0,5,悬挂物体绝对没有问题。事实上,它应该抛出 OutOfMemoryException 而不是崩溃并且没有异常。我正在使用这些参数: -Xmn256m -Xms768m -Xmx3000m -XX:NewRatio=2 -server -verbosegc -XX:PermSize=256m -XX:MaxPermSize=256m -XX:SurvivorRatio=8 -XX:+UseParallelGC -XX:ParallelGCThreads= 2 -XX:+UseParallelOldGC
    • 我强烈建议您不要修改 JVM 参数,直到您有可靠的配置工作!此外,此信息非常重要,应该放在您的问题中。
    猜你喜欢
    • 2012-03-04
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 2012-07-04
    • 2011-11-14
    • 2013-04-09
    相关资源
    最近更新 更多