JVM 崩溃,错误为“无法分配内存”(errno=12)

2022-09-02 13:23:16

我的代码崩溃并显示此错误消息

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)

内存不足,无法继续 Java 运行时环境。本机内存分配 (malloc) 无法分配 2712666112 字节来提交保留内存。包含更多信息的错误报告文件将另存为:/tmp/jvm-29955/hs_error.log'

以下是生成的内容:hs_error.log file

https://pastebin.com/yqF2Yy4P

崩溃日志中的这一行对我来说似乎很有趣:

Memory: 4k page, physical 98823196k(691424k free), swap 1048572k(0k free)

这是否意味着计算机有内存但交换空间不足?

这是来自崩溃日志的meminfo,但我真的不知道如何解释它,比如MemFree和MemAvailable有什么区别?此过程需要多少内存?

/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

答案 1

可能的解决方案:

  • 减少系统上的内存负载
  • 增加物理内存或交换空间
  • 检查交换后备存储是否已满
  • 在 64 位操作系统上使用 64 位 Java
  • 减小 Java 堆大小 (-Xmx/-Xms)
  • 减少 Java 线程数
  • 减小 Java 线程堆栈大小 (-Xss)
  • 使用 -XX:ReservedCodeCacheSize= 设置更大的代码缓存
  • 如果你有许多上下文战争部署在你的雄猫上,试着减少它们

答案 2

正如Scary Wombat所提到的,JVM试图分配2712666112字节(2.7 Gb)的内存,而您只有691424000字节(0.69 Gb)的可用物理内存,而交换中没有可用的内存。