You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

服务器JRE内存不足问题排查求助(系统内存充足)

Java程序向RabbitMQ推送消息时OOM问题排查指导

问题背景

在CentOS Linux服务器上运行Java程序向RabbitMQ推送信息时,程序因Out of Memory Error中断,日志内容较多,刚接触Java,需要排查方向指导。

相关错误日志

JVM内存分配失败日志

# Java运行时环境无法继续执行,内存不足。
# 本地内存分配(mmap)无法映射55574528字节以提交预留内存。

# 内存溢出错误 (os_linux.cpp:2795), pid=43653, tid=0x00007f46186b4700
#
# JRE版本: OpenJDK Runtime Environment (8.0_332-b09) (build 1.8.0_332-b09)
# Java虚拟机: OpenJDK 64-Bit Server VM (25.332-b09 混合模式 linux-amd64 压缩指针)
# 无法生成核心转储。核心转储已禁用。要启用核心转储,请在再次启动Java前尝试执行 "ulimit -c unlimited"
#

线程栈日志

---------------  线程信息  ---------------

当前线程 (0x00007f46280ea000):  VMThread [栈: 0x00007f46185b5000,0x00007f46186b5000] [id=43657]

栈: [0x00007f46185b5000,0x00007f46186b5000],  sp=0x00007f46186b3330, 空闲空间=1016k
本地帧: (J=编译后的Java代码, j=解释执行代码, Vv=虚拟机代码, C=本地代码)
V  [libjvm.so+0xb65ecd]  VMError::report_and_die()+0x1cd
V  [libjvm.so+0x5075aa]  report_vm_out_of_memory(char const*, int, unsigned long, VMErrorType, char const*)+0xaa
V  [libjvm.so+0x941588]  os::pd_commit_memory(char*, unsigned long, unsigned long, bool)+0xd8
V  [libjvm.so+0x938d9e]  os::commit_memory(char*, unsigned long, unsigned long, bool)+0x2e
V  [libjvm.so+0x9b902b]  PSVirtualSpace::expand_by(unsigned long)+0x5b
V  [libjvm.so+0x9a90ca]  PSOldGen::expand_by(unsigned long) [clone .part.113]+0x2a
V  [libjvm.so+0x9a929b]  PSOldGen::expand(unsigned long) [clone .part.115]+0xdb
V  [libjvm.so+0x9a9be8]  PSOldGen::resize(unsigned long)+0x198
V  [libjvm.so+0x9af58c]  PSParallelCompact::invoke_no_policy(bool)+0x9dc
V  [libjvm.so+0x9b6b7d]  PSScavenge::invoke()+0x17d
V  [libjvm.so+0x968c73]  ParallelScavengeHeap::failed_mem_allocate(unsigned long)+0x63
V  [libjvm.so+0xb67b23]  VM_ParallelGCFailedAllocation::doit()+0x93
V  [libjvm.so+0xb6cfe5]  VM_Operation::evaluate()+0x55
V  [libjvm.so+0xb6afaa]  VMThread::evaluate_operation(VM_Operation*)+0x11a
V  [libjvm.so+0xb6b419]  VMThread::loop()+0x219
V  [libjvm.so+0xb6b8d2]  VMThread::run()+0x92
V  [libjvm.so+0x93e4f2]  java_start(Thread*)+0xf2

虚拟机操作 (0x00007f463172d3e0): ParallelGCFailedAllocation, 模式: 安全点, 由线程 0x00007f4628063800 请求

系统内存信息

---------------  系统信息  ---------------

操作系统:CentOS Linux release 7.8.2003 (Core)

uname:Linux 3.10.0-1160.62.1.el7.x86_64 #1 SMP Tue Apr 5 16:57:59 UTC 2022 x86_64
libc:glibc 2.17 NPTL 2.17 
资源限制: 栈大小 8192k, 核心转储大小 0k, 最大进程数 4096, 最大文件句柄数 4096, 地址空间无限制
系统负载:4.81 6.40 3.68

/proc/meminfo:
总内存:        3861256 kB
空闲内存:          108460 kB
可用内存:      19104 kB
缓冲区:               0 kB
缓存:            22388 kB
交换缓存:         7600 kB
活跃内存:          2577112 kB
非活跃内存:         971876 kB
活跃匿名内存:    2570780 kB
非活跃匿名内存:   957160 kB
活跃文件内存:       6332 kB
非活跃文件内存:    14716 kB
不可回收内存:           0 kB
锁定内存:               0 kB
总交换空间:       1048572 kB
空闲交换空间:            780 kB
脏页:                20 kB
回写页:             0 kB
匿名页:       3519584 kB
映射页:             3356 kB
共享内存:              1184 kB
Slab内存:              85128 kB
可回收Slab:      40496 kB
不可回收Slab:        44632 kB
内核栈:        7872 kB
页表:        20908 kB
NFS不稳定页:          0 kB
Bounce页:                0 kB
回写临时页:          0 kB
提交限制:     2979200 kB
已提交地址空间:    3444760 kB
虚拟内存总量:   34359738367 kB
已用虚拟内存:      183428 kB
虚拟内存空闲块:   34359310332 kB
每个CPU内存:            24064 kB
硬件损坏内存:     0 kB
匿名大页:    448512 kB
CMA总内存:              0 kB
CMA空闲内存:               0 kB
大页总数:       0
空闲大页:        0
预留大页:        0
超额大页:        0
大页大小:       2048 kB
直接映射4k:       94016 kB
直接映射2M:     4100096 kB
直接映射1G:     2097152 kB

内存情况分析

你看到的MemFree(108460KB)只是系统未被使用的内存,但实际可用内存要看MemAvailable(仅19104KB),这个值才是系统能分配给新应用或扩展现有应用的内存。同时:

  • 交换空间SwapFree只剩780KB,几乎耗尽,系统无法通过交换释放内存
  • Committed_AS(3444760KB)已经超过CommitLimit(2979200KB),说明系统已提交的内存总量超过了内核允许的上限,这会直接导致内存分配失败

排查方向

  • 检查JVM内存参数配置:查看启动Java程序时的-Xmx(最大堆内存)、-Xms(初始堆内存)参数。如果-Xmx设置过大,超过系统MemAvailable,会导致JVM无法扩展堆内存;建议将-Xms和-Xmx设为相同值,避免JVM频繁扩容堆内存。
  • 排查内存泄漏:程序向RabbitMQ推送消息时,可能存在消息对象未及时释放、连接/通道未关闭、队列堆积等情况。可以通过以下方式分析:
    • 开启GC日志:添加-XX:+PrintGCDetails -XX:+PrintGCTimeStamps参数,查看GC频率和内存回收情况
    • 使用jmap工具生成堆转储文件:执行jmap -dump:format=b,file=heapdump.hprof <pid>,分析哪些对象占用大量内存
  • 清理系统内存压力:使用top或htop命令查看其他进程的内存占用情况,关闭不必要的进程释放内存;如果系统长期内存不足,考虑升级服务器内存。
  • 调整GC策略:当前使用的是ParallelScavenge收集器,老年代扩展失败说明GC无法有效回收内存。可以尝试调整GC参数,比如增大老年代比例(-XX:NewRatio=2),或者更换为CMS收集器(-XX:+UseConcMarkSweepGC),减少GC停顿时间和内存碎片。

内容的提问来源于stack exchange,提问作者Robin wong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:27:23