我的盒子有35.84 GB的RAM,当我启动我的Java进程时,我将-xmx28g参数传递给它,所以它的使用方式应该小于可用的最大RAM.
我按如下方式运行jstat:
# jstat -gccause -t `pgrep java` 60000
在进程被杀之前jstat的最后几行输出是:
Time S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC 14236.1 99.98 0.00 69.80 99.40 49.88 1011 232.305 11 171.041 403.347 unknown GCCause No GC 14296.2 93.02 0.00 65.79 99.43 49.88 1015 233.000 11 171.041 404.041 unknown GCCause No GC 14356.1 79.20 0.00 80.50 99.55 49.88 1019 233.945 11 171.041 404.986 unknown GCCause No GC 14416.2 0.00 99.98 24.32 99.64 49.88 1024 234.945 11 171.041 405.987 unknown GCCause No GC
这似乎是这次在/ var / log / syslog中发生的事情:https://gist.github.com/1369135
除了我的java应用程序之外,这台服务器上什么都没有运行.这是怎么回事?
编辑:我正在运行java版本1.6.0_20,我在启动时传递给java的唯一值得注意的参数是“-server -Xmx28g”.我没有使用应用程序服务器,但我的应用程序嵌入了“简单的Web框架”.
我的结论是:
>您的JVM实际上使用的功率远远超过28Gb;即你有非常重要的非堆内存使用率
>操作系统未配置足够的交换空间.
我会尝试添加更多的交换空间,以便操作系统可以在紧急情况下更换部分应用程序.
或者,减少JVM的堆大小.
请注意,“ – Xmx …”设置最大堆大小,而不是JVM可以使用的最大内存量. JVM将一些东西放在堆外,包括用于线程堆栈的内存和应用程序正在使用的内存映射文件.
系统日志确认它是工作中的OOM杀手.
In what way does the linked syslog say so?
它说:
Nov 15 13:53:49 ip-10-71-94-36 kernel: [3707038.606133] Out of memory: kill process 6368 (run.sh) score 4747288 or a child Nov 15 13:53:49 ip-10-71-94-36 kernel: [3707038.606146] Killed process 9359 (java)
The console says that java was killed,not that it quit.
正确.它被操作系统的OOM杀手杀死了.
If it had run out of memory it would typically throw an OutOfMemory exception,which it didn’t.
如果你填满了Java堆就会发生这种情况.
这不是这里发生的事情.实际问题是没有足够的物理RAM来容纳Java堆. OOM杀手处理它……
I’m running with such a huge heap because I need to store millions of objects each of which require several kilobytes of RAM.
不幸的是,您尝试使用比系统上可用的RAM更多的RAM.这导致虚拟内存崩溃,影响整个操作系统.
当系统开始严重崩溃时,OOM杀手(而不是JVM)会将您的Java进程识别为问题的原因.然后它(用SIGKILL)杀死它以保护系统的其余部分.如果没有,则存在整个系统完全锁定并需要重新启动的风险.
最后,你说:
My Box has 35.84 GB of RAM …
这是一个奇怪的价值. 32 GiB是34,359,738,368字节或34.35 GB.
但基于此和观察到的行为,我怀疑这是可用的虚拟内存而不是物理RAM.或者,您的“盒子”可以是在虚拟机管理程序级别启用RAM过量使用的虚拟机.