GC-MetaScace的理解

一些看过Java8以后的垃圾回收日志的一般会对这么一句话感到很困惑:

Metaspace used 2425K, capacity 4498K, committed 4864K, reserved 1056768K
class space used 262K, capacity 386K, committed 512K, reserved 1048576K

第一个问题是,按照一般的理解,metaspace似乎是一个整体,怎么还分成了四个部分?

第二个问题是,怎么metaspace之后,还有一个class space?两者之间的关系是怎样的?

先来看一幅图:

  GC-MetaScace的理解  

首先可以看到的是,这些used,capacity,committedreserved并不纯粹是JVM的概念,它和操作系统相关。

先来看committedreservedreserved是指,操作系统已经为该进程“保留”的。所谓的保留,更加接近一种记账的概念,就是操作系统承诺说一大块连续的内存已经是你这个进程的了。注意的是,这里强调的是连续的内存,并且强调的是一种名义归属。那么实际上这一大块内存有没有真实对应的物理内存呢?答案是不知道。

那么什么时候才知道呢?等进程committed的时候。当进程真的要用这个连续地址空间的时候,操作系统才会分配真正的内存。所以,这也就是意味着,这个过程会失败。

举个例子来说,就好比张三找李四借钱,张三说借1000,李四在本子上记录了一笔说可以,借给你了,但是暂时不能给你,等你要用的时候再来领。于是过了一天,张三来领了300,这300就是committed的,之前那1000就是reserved的。很显然,如果李四给太多人都记了一笔,说不定等张三去借的时候,就没有了。

因此,这个reserved更加接近记账的概念。

usedcapacity就是JVM的概念了。这两个概念非常接近JVM一些集合框架的概念。一些Java集合框架,比如某种List的实现,会有sizecapacity的概念。比如说ArrayList的实现里面就有capacitysize的概念。假如说我创建了一个可以存放30个元素的ArrayList,但是我实际上只放了20个元素,那么capacity就是30,而size就是20.这里的sizeused就是一个概念。那么“元素”则是一个个内存块"block“。

capacitycommitted的关系也可以此类比,只不过capacity反而对应到usedcommitted对应到capacity,而所谓的”元素“,就是chunk

至于class space,要记住的是,metaspace并不是全部用来放类对象的。比如说,因为每一个ClassLoader都被分配了一块内存,这块内存可能并没有被用完,于是就会有一些内存碎片;metaspace还需要放所谓静态变量。所以,class space是指实际上被用于放class的那块内存的和。

上一篇:MySql事务隔离级别-已提交读(READ COMMITTED)


下一篇:小程序websocket心跳库——websocket-heartbeat-miniprogram