Java崩溃的应用程序 - 如何找出Java崩溃的原因?
我的java服务器开始反复崩溃,我找不到原因。Java崩溃的应用程序 - 如何找出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
我有0.5GB,一个GC运行后,使所有的时间它提出了从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 "[email protected]" [_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
...
听起来像内存泄漏。 gc只能清除不再被引用的对象。而且,如果您的应用程序(或服务器本身)没有“释放”未使用的资源,一段时间后甚至3GB是不够的。
Profiler可能有助于识别意外增长的数据结构。
想法:用-verbose:gc
选项启动服务器,并检查它在死亡之前发生了什么。减少测试堆空间,以便您不必等待很长时间。如果是内存泄漏,我希望你能看到常规的完整gc循环,gc每次运行时都可以释放更少的内存。
更新
我被outofmemoryerror
标签误导。事实上,这是一个JVM崩溃,你只能尝试更新已安装的Java。已经有一些关于“SIGSEGV(0xb)”的报告崩溃了版本1.6.0_17和1.6.0_18(like this question on SO)。
这是一个JVM内部问题。
如果你有“内存问题”意味着你担心你的物理硬件有缺陷,你应该强烈考虑对它进行压力测试。
对于传统的PC来说,通常的做法是用memtest86。最新版本似乎可以从这里获得:http://www.memtest.org/
如果内存通过memtest86通宵测试,你可以肯定它可以正常工作。
当你说你为JVM分配了3 GB的空间时,这是堆大小还是总大小(可能会比较大)具有3 GB堆的JVM总共可以使用4 GB的缓存。
如果JVM已经在GC坠毁,我会检查你有JVM的当前版本,如Java 6更新23
是什么崩溃?有时候,其他人会报告同样的崩溃,您可以通过谷歌搜索它。有时候有一个建议的解决方案。
从您链接的崩溃文档中,错误是一个SIGSEGV,它是读取/写入本机内存故障。线程堆栈显示它在JVM代码中崩溃。
Current thread (0x00007fe899755800): JavaThread "[email protected]" [_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错误,或者内存损坏。
是否有任何JNI组件? – 2011-02-15 12:29:26
事实上,你'做'GC多次应该设置警钟。如果你不做任何GC并依靠JVM来执行它,那么服务器的行为是什么? – anirvan 2011-02-15 12:30:11
什么程序正在运行? Java自己执行垃圾收集,但是如果程序引发内存泄漏,这可能是不够的。 – 2011-02-15 12:31:02