前篇:学习笔记之JVM OOM内存溢出模拟及JVM打印日志分析(环境win10)
浏览器请求 localhost:8888 会者curl localhost:8888,打印出如下日志
8MB
Code Cache committed:2555904 used:1713408
Metaspace committed:6553600 used:6251992
Compressed Class Space committed:786432 used:706192
Par Eden Space committed:3407872 used:1106784
Par Survivor Space committed:393216 used:79352
CMS Old Gen committed:16777216 used:10016616
[GC (CMS Initial Mark) [1 CMS-initial-mark: 9781K(16384K)] 10961K(20096K), 0.0024302 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.011/0.011 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (CMS Final Remark) [YG occupancy: 1179 K (3712 K)][Rescan (parallel) , 0.0008601 secs][weak refs processing, 0.0005156 secs][class unloading, 0.0026372 secs][scrub symbol table, 0.0021037 secs][scrub string
table, 0.0014837 secs][1 CMS-remark: 9781K(16384K)] 10961K(20096K), 0.0163186 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
9MB
Code Cache committed:2555904 used:1721792
Metaspace committed:6553600 used:6258120
used ,capacity ,committed ,reserved 具体都代表什么?
- used:加载的类的空间量。
- capacity:当前分配块的元数据的空间。
- committed:空间块的数量。
- reserved:元数据的空间保留(但不一定提交)的量
示意图如下:
Metaspace由一个或多个虚拟空间组成,虚拟空间的分配单元是Chunk,其中Chunk使用列表进行维护。
当使用一个classLoader加载一个类时,过程如下:
1、当前classLoader是否有对应的Chunk且有足够的空间。
2、查找空闲列表中的有没有空闲的Chunk。
3、如果没有,就从当前虚拟空间中分配一个新的Chunk,这个时候会把对应的内存进行Commit,这个动作就是提交。
4、如果当前虚拟空间不足,则预留(reserves)一个新的虚拟空间。
reserved是jvm启动时根据参数和操作系统预留的内存大小。
committed是指那些被commit的Chunk大小之和;
capacity是指那些被实际分配的Chunk大小之和;
因为有GC的存在,有些Chunk的数据可能会被回收,那么这些Chunk属于committe的一部分,但不属于capacity
另外,这些被分配的Chunk,基本很难被100%用完,存在碎片内存的情况,这些Chunk实际被使用的内存之和即used的大小;
所以,如何一个服务中被代理的方法特别特别多,就可能存在创建特别特别多的classLoader对象,一个classLoader对象至少需要一个Chunk,这个Chunk可能只放一个class信息,那么就存在特别特别严重的内存碎片,继而就存在一个隐患,可能发生特别频繁的FGC,而且是由Metaspace不足引起的。
由以上日志可以打印出CMS的垃圾回收的过程
[GC (CMS Initial Mark) [1 CMS-initial-mark: 9781K(16384K)] ===>初始标记
[CMS-concurrent-mark-start] ===>并发标记
[CMS-concurrent-mark: 0.011/0.011 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]
[CMS-concurrent-preclean-start] ===>预清理
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (CMS Final Remark) [YG occupancy: 1179 K (3712 K)][Rescan (parallel) ===> 最终标记
[CMS-concurrent-sweep-start] ===>交换
[CMS-concurrent-sweep: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-reset-start] ===>重置
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]