附图,JVM GC日志如下:
那么在metaspace 那一行的used, capacity,committed, reserved分别代表什么意思呢?
盗图如下:
- used: 加载的类的空间量
- capacity: 当前分配块的源数据空间
- committed: 空间块的大小
- reserved: 元数据的空间保留的量(并不一定是提交)
Metaspace是由一个或则多个虚拟空间组成,虚拟空间的单位是Chunk.
当使用一个classLoader去加载类的时候,执行过程如下:
- 当前的classLoader是否有对应的Chunk, 且空间数量是否充足
- 查询空闲列表中有没有空闲的Chunk,
- 如果没有,就从当前的虚拟空间中分配一个Chunk,这个时候会把对应的空间进行提交,这个就是commit.
- 如果当前的虚拟空间不足,则会预留一个新的虚拟空间
reserved是JVM启动时根据参数和操作系统预留的内存大小
committed是被commit的Chunk空间
capacity是那些被实际分配的Chunk大小之和
因为有GC的存在,有些Chunk的数据可能会被回收,那么这些Chunk属于committe的一部分,但不属于capacity
另外,这些被分配的Chunk,基本很难被100%用完,存在碎片内存的情况,这些Chunk实际被使用的内存之和即used的大小;
所以,如何一个服务中被代理的方法特别特别多,就可能存在创建特别特别多的classLoader对象,一个classLoader对象至少需要一个Chunk,这个Chunk可能只放一个class信息,那么就存在特别特别严重的内存碎片,继而就存在一个隐患,可能发生特别频繁的FGC,而且是由Metaspace不足引起的。