OOM(Java heap space)排查流程记录

springboot项目部署在linux中,出现了OOM(Java heap space),记录一下排查流程

1、由于项目并没有设置jvm的属性,所以先查看一下默认的内存有多大

	#在Java环境中获取堆内存大小的信息
	java -XX:+PrintFlagsFinal -version | grep HeapSize

在linux中执行这段命令,会得到

	uintx ErgoHeapSizeLimit = 0 {product}
	uintx HeapSizePerGCThread = 87241520 {product}
	uintx InitialHeapSize := 125829120 {product}
	uintx LargePageHeapSizeThreshold = 134217728 {product}
	uintx MaxHeapSize := 2006974464 {product}

ErgoHeapSizeLimit:这是Ergonomics堆大小限制,它是根据系统配置和运行时情况自动调整的。
HeapSizePerGCThread:这是每个垃圾回收线程的堆大小,它指定了每个垃圾回收线程可以使用的堆内存量。
InitialHeapSize:这是Java虚拟机在启动时分配的初始堆大小。
LargePageHeapSizeThreshold:这是启用大页内存的阈值,当堆大小达到或超过该阈值时,Java虚拟机将尝试使用大页内存。
MaxHeapSize:这是Java虚拟机允许的最大堆大小。当堆的大小达到这个限制时,Java虚拟机将停止分配更多的内存。

2、获取指定 Java 进程的堆内存信息。

	#获取指定 Java 进程的堆内存信息。 <PID>是自己的程序PID
	sudo jcmd <PID> GC.heap_info

我执行这段代码是出现了jcmd: command not found错误,原因是jcmd命令的路径没有包含在sudo的环境变量中。
那么可以使用绝对路径来执行jcmd命令

	#获取java路径
	which java

得到绝对路径之后再去执行就可以了

	#使用绝对路径执行jcmd命令 <PID>是自己的程序PID
	sudo /usr/local/jdk1.8.0_371/bin/jcmd <PID> GC.heap_info

可以得到这么样的一个结果

PSYoungGen total 461824K, used 204150K [0x00000000d8200000, 0x00000000ff280000, 0x0000000100000000)
eden space 283648K, 71% used [0x00000000d8200000,0x00000000e495d838,0x00000000e9700000)
from space 178176K, 0% used [0x00000000f4480000,0x00000000f4480000,0x00000000ff280000)
to space 177664K, 0% used [0x00000000e9700000,0x00000000e9700000,0x00000000f4480000)
ParOldGen total 971264K, used 232467K [0x0000000088600000, 0x00000000c3a80000, 0x00000000d8200000)
object space 971264K, 23% used [0x0000000088600000,0x0000000096904ee0,0x00000000c3a80000)
Metaspace used 104851K, capacity 109680K, committed 111064K, reserved 1146880K
class space used 12467K, capacity 13257K, committed 13528K, reserved 1048576K

根据提供的堆内存信息,可以得到以下解释:

PSYoungGen 是年轻代的名称,表示新生代堆内存。
    total 461824K:新生代总大小为 461824K(约 451 MB)。
    used 204150K:新生代已使用的大小为 204150K(约 199 MB)。
    [0x00000000d8200000, 0x00000000ff280000, 0x0000000100000000):新生代的内存地址范围。

eden space:表示 Eden 区的大小和使用情况。
    283648K:Eden 区的大小为 283648K(约 277 MB)。
    71% used:Eden 区已使用的比例为 71%。

from space:表示 Survivor From 区的大小和使用情况。
    178176K:Survivor From 区的大小为 178176K(约 174 MB)。
    0% used:Survivor From 区未被使用。

to space:表示 Survivor To 区的大小和使用情况。
    177664K:Survivor To 区的大小为 177664K(约 173 MB)。
    0% used:Survivor To 区未被使用。

ParOldGen 是老年代的名称,表示老年代堆内存。
    total 971264K:老年代总大小为 971264K(约 948 MB)。
    used 232467K:老年代已使用的大小为 232467K(约 227 MB)。
    [0x0000000088600000, 0x00000000c3a80000, 0x00000000d8200000):老年代的内存地址范围。

Metaspace:表示元数据空间(Metaspace)的使用情况。
    used 104851K:元数据空间已使用的大小为 104851K(约 102 MB)。
    capacity 109680K:元数据空间的容量为 109680K(约 107 MB)。
    committed 111064K:元数据空间的已分配大小为 111064K(约 108 MB)。
    reserved 1146880K:元数据空间的保留大小为 1146880K(约 1122 MB)。

class space:表示类空间的使用情况。
    used 12467K:类空间已使用的大小为 12467K(约 12 MB)。
    capacity 13257K:类空间的容量为 13257K(约 13 MB)。
    committed 13528K:类空间的已分配大小为 13528K(约 13 MB)。
    reserved 1048576K:类空间的保留大小为 1048576K(约 1024 MB)。

这些信息描述了 Java 进程的堆内存使用情况,包括新生代、老年代、元数据空间和类空间的大小和使用情况。

3、分析 Java 堆内存的使用情况和对象分布

	#分析 Java 堆内存的使用情况和对象分布 <PID>是自己的程序PID
	sudo /usr/local/jdk1.8.0_371/bin/jmap -histo <PID>

这个命令会得到一串很长的堆内存的使用情况,如果太长展示不如来的话可以 通过管道符查看指定行数

sudo /usr/local/jdk1.8.0_371/bin/jmap -histo 1850336 | head -n <行数>

4、查看服务器物理内存

	#显示系统内存的使用情况
	free -h
total:表示系统内存的总大小。
used:表示已使用的内存大小。
free:表示可用的空闲内存大小。
shared:表示被共享的内存大小。
buffers:表示被缓冲的内存大小。
cached:表示被缓存的内存大小。

5、生成.hprof 文件进行分析

	#生成.hprof 路径就是.hprof文件生成的地方,<PID>是自己的程序PID
	sudo /usr/local/jdk1.8.0_371/bin/jmap -dump:format=b,file=/data/install/logs/file.hprof  <PID>

生成文件后可以下载下来 使用JProfiler等工具进行解析
可以参考这个

https://blog.csdn.net/qq_42262444/article/details/133163454

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值