[英]JVM crashes with error='Cannot allocate memory' (errno=12)
My code crashes with this error message我的代码因此错误消息而崩溃
Executing "/usr/bin/java com.utils.BotFilter"
OpenJDK 64-Bit Server VM warning: INFO:
os::commit_memory(0x0000000357c80000, 2712666112, 0) failed;
error='Cannot allocate memory' (errno=12)
There is insufficient memory for the Java Runtime Environment to continue.
没有足够的内存供 Java 运行时环境继续使用。 Native memory allocation (malloc) failed to allocate 2712666112 bytes for committing reserved memory.
本机内存分配 (malloc) 未能为提交保留内存分配 2712666112 字节。 An error report file with more information is saved as: /tmp/jvm-29955/hs_error.log`
包含更多信息的错误报告文件保存为:/tmp/jvm-29955/hs_error.log`
Here is the content of the generated hs_error.log file
:以下是生成的
hs_error.log file
的内容:
https://pastebin.com/yqF2Yy4P https://pastebin.com/yqF2Yy4P
This line from crash log seems interesting to me:崩溃日志中的这一行对我来说似乎很有趣:
Memory: 4k page, physical 98823196k(691424k free), swap 1048572k(0k free)
Does it mean that the machine has memory but is running out of swap space?这是否意味着机器有内存但交换空间不足?
Here is meminfo from the crash log but I don't really know how to interpret it, like what is the difference between MemFree and MemAvailable?这是崩溃日志中的 meminfo,但我真的不知道如何解释它,比如 MemFree 和 MemAvailable 之间有什么区别? How much memory is this process taking?
这个过程占用了多少内存?
/proc/meminfo
: /proc/meminfo
:
MemTotal: 98823196 kB
MemFree: 691424 kB
MemAvailable: 2204348 kB
Buffers: 145568 kB
Cached: 2799624 kB
SwapCached: 304368 kB
Active: 81524540 kB
Inactive: 14120408 kB
Active(anon): 80936988 kB
Inactive(anon): 13139448 kB
Active(file): 587552 kB
Inactive(file): 980960 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 1048572 kB
SwapFree: 0 kB
Dirty: 1332 kB
Writeback: 0 kB
AnonPages: 92395828 kB
Mapped: 120980 kB
Shmem: 1376052 kB
Slab: 594476 kB
SReclaimable: 282296 kB
SUnreclaim: 312180 kB
KernelStack: 317648 kB
PageTables: 238412 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 50460168 kB
Committed_AS: 114163748 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 314408 kB
VmallocChunk: 34308158464 kB
HardwareCorrupted: 0 kB
AnonHugePages: 50071552 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 116924 kB
DirectMap2M: 5115904 kB
DirectMap1G: 95420416 kB
Possible solutions:可能的解决方案:
正如Scary Wombat 所提到的,JVM 试图分配 2712666112 字节(2.7 Gb)的内存,而您只有 691424000 字节(0.69 Gb)的空闲物理内存,交换中没有任何可用空间。
Another possibility (which I encountered just now) would be bad settings for "overcommit memory" on linux.另一种可能性(我刚才遇到的)是 linux 上“过量使用内存”的错误设置。
In my situation, /proc/sys/vm/overcommit_memory
was set to "2" and /proc/sys/vm/overcommit_ratio
to "50" , meaning "don't ever overcommit and only allow allocation of 50% of the available RAM+Swap".在我的情况下,
/proc/sys/vm/overcommit_memory
设置为 "2" 和/proc/sys/vm/overcommit_ratio
为 "50" ,意思是“不要过度使用,只允许分配 50% 的可用 RAM +交换”。
That's a pretty deceptive problem, since there can be a lot of memory available, but allocations still fail for apparently no reason.这是一个相当具有欺骗性的问题,因为可能有大量可用内存,但分配仍然毫无理由地失败。
The settings can be changed to the default (overcommit in a sensible way) for now (until a restart):现在(直到重新启动)可以将设置更改为默认值(以合理的方式过度使用):
echo 0 >/proc/sys/vm/overcommit_memory
... or permanently: ...或永久:
echo "vm.overcommit_memory=0 >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf # apply it immediately
Note: this can also partly be diagnosed by looking at the output of /proc/meminfo
:注意:这也可以通过查看
/proc/meminfo
的输出来部分诊断:
...
CommitLimit: 45329388 kB
Committed_AS: 44818080 kB
...
In the example in the question, Committed_AS
is much higher than CommitLimit
, indicating (together with the fact that allocations fail) that overcommit is enabled, while here both values are close together, meaning that the limit is strictly enforced.在问题的示例中,
Committed_AS
远高于CommitLimit
,表明(连同分配失败的事实)启用了过度使用,而此处两个值接近在一起,这意味着严格执行限制。
An excellent detailed explanation of these settings and their effect (as well as when it makes sense to modify them) can be found in this pivotal blog entry .在这个关键的博客条目中可以找到对这些设置及其效果(以及何时修改它们有意义)的出色详细说明。 (Tl;dr: messing with overcommit is useful if you don't want critical processes to use swap)
(Tl; dr:如果您不希望关键进程使用交换,那么处理过度使用会很有用)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.