2

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

4 回答 4

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 错误,也可能是内存损坏。

于 2011-02-15T13:51:37.847 回答
0

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

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


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


更新

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

这是JVM内部问题。

于 2011-02-15T12:34:25.313 回答
0

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

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

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

于 2011-02-15T12:45:11.217 回答
0

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

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

车祸是怎么回事?有时其他人报告了同样的崩溃,您可以搜索它。有时会有建议的解决方案。

于 2011-02-15T12:56:40.080 回答