JVM元空间溢出的排除思路

背景:

java的应用我们为了防止元空间的无限扩展,一般都会设置MaxMetaSpace参数,一般来说只要这个值是512M或者1G左右就足够了,不过今天遇到一个meta空间溢出问题,简单记录下排除的思路

meta元空间溢出

最开始的现象是不停的进行fullgc,但是gc后新生代和年老代的大小都不怎么变化,此时应该是因为gc占用了应用的执行,导致此时其实应用很少能产生对象出来了,所以这就是看到fullgc后新生代和老年代不怎么变化的原因,在经过了几十次gc后,发生OOM: metaspace异常,以下记下排除思路:
1.首先使用>jstat -gcutil pid 1000 5

排除下gc的情况,包括此时Meta的空间占用情况
2.由于元空间的数据一般都是分配给类加载器的,我们需要使用命令jmap -clstats pid看一下当前系统中有哪些类加载器:

3.查看类加载器加载的所有类的信息,命令如下jcmd pid GC.class_stats :

关键的信息有加载类的名称(ClassName)、每个类所占据的字节(KlassBytes)、每个类的实例所占据的字节(InstBytes)、每个类中方法的数量(MethodCount)、字节码所占据的空间(ByteCodes)),这里需要重点看的就是有没有重复加载的类,也就是对ClassName去重后统计数量,如果同一个ClassName出现次数超过一次,证明是由不同的类加载器加载的,因为正常来说由于类加载器的双亲委派机制,一个类一般都只是由一个类加载器加载的,所以如果这里一个类有多个类加载器加载,就需要判断下是否是这个类加载器导致的问题了,那么下一步就是找出Class对象对应的类加载器了

4.使用MAT内存分析工具分析Class对象对应的类加载器

选择MAT界面上的Histogram界面,选择有问题的Class实例,然后右键 PATH TO GC ROOT,查看对应的类加载器即可

5.定位是哪一行代码生产的类加载器加载的类

加上JVM 参数:-XX:+UnlockDiagnosticVMOptions后进行本地调试,单步调试的时候当类加载器加载类的时候就会把信息打印到控制台中,这样就可以一步一步定位到哪里加载的了

相关推荐
源分享2 天前
Java线程同步的多种实现方法(非常详细)
java·开发语言·jvm
JAVA9652 天前
JAVA面试-JVM篇 03-JVM运行时数据区哪些是线程私有的哪些是共享的
java·jvm·面试
伶俜663 天前
鸿蒙原生应用实战(十八)ArkUI 记账本:SQLite 账单 + 图表统计 + 分类管理
jvm·sqlite·harmonyos
IronMurphy3 天前
多线程问!
java·jvm·spring
unique3 天前
AI Coding 采集方案探索
jvm·人工智能·oracle
cfm_29144 天前
JVM GC日志解析
jvm
不良使4 天前
鸿蒙PC迁移:使用Electron`logseq-master-ohos` 鸿蒙适配全记录
jvm·electron·harmonyos
cfm_29144 天前
JVM深度详解:Class常量池、运行时常量池、字符串常量池、包装类对象池
java·jvm
JAVA9654 天前
JAVA面试-JVM篇 02-G1垃圾收集器的工作原理是什么与CMS的区别
java·jvm·面试