Java崩溃的应用程序 - 如何找出Java崩溃的原因?

时间:2011-02-15 12:27:05

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

我的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
...

4 个答案:

答案 0 :(得分: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错误,也可能是内存损坏。

答案 1 :(得分:0)

听起来像是内存泄漏。 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内部问题。

答案 2 :(得分:0)

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

对于传统PC来说,通常的方法是使用memtest86。最新版本似乎可从此处获得:http://www.memtest.org/

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

答案 3 :(得分:0)

当你说你为JVM分配3 GB时,这是堆大小还是总大小(可能会大得多),例如具有3 GB堆的JVM可以使用总计4 GB的clsoe。

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

什么是撞车?有时候其他人会报告相同的崩溃,你可以谷歌搜索它。有时会有一个建议的解决方案。