ZGC-颜色指针(03)
目录
什么是颜色指针?
1.颜色指针是ZGC的一个核心概念,它使ZGC能够查找、标记、定位和重映射对象。
2.不支持32位平台。
3.不支持压缩Oops。
4.实现需要虚拟地址屏蔽,这可以在硬件、操作系统或软件上实现。
5.有些文章会将其定义为是一种将信息存储在指针中的技术。
指针布局
上图显示了64位指针布局:
1.低42位:
.用于描述对象地址(也就是应用程序可以使用的堆空间,java堆)。
.42位地址最大寻址空间就是4TB,这就是ZGC一直宣称自己最大支持4TB内存原因(未来可扩展)。
设系统地址总线为N位,则最大寻址空间 = 2^N Byte
例如32位地址线,最大寻址空间为:
.2^32 Byte =4294967196Byte = 4197304kByte =4096MByte =4GB
.1太字节(tb)=1024 千兆字节(GB)
2.颜色指针(虚拟内存):
.1-bit: Marked0 [4TB ~ 8TB) 称为M0地址空间
.1-bit: Marked1 [8TB ~ 12TB) 称为M1地址空间
.1-bit: Remapped [16TB ~ 20TB) 称为Remapped空间 (注意:从16TB开始)
.1-bit: 预留 [12TB ~ 16TB) 预留未使用
3.高18位:
预留
视图对应的内存
1.当应用程序创建对象时,首先在堆空间申请一个虚拟地址,但该虚拟地址并不会映射到真正的物理地址,
而是映射到三个视图(M0、M1和Remapped),然后通过三视图映射到真正的物理空间。
2.ZGC也会为M0、M1和Remapped分别申请一个虚拟地址,且这三个虚拟地址对应同一个物理地址,
但这三个空间在同一时间有且只有一个空间有效。
颜色指针的作用
1.主要概念
1.将对象存活信息存储在42~45位中,这与传统的垃圾回收并将对象存活信息放在对象头中完全不同,
并且因为是寄存器访问,所以速度比访问内存更快。
2.颜色指针和读屏障,这两种技术的结合是ZGC能高效回收的核心基础。
2.什么是在Java对象头?
在Hotspot虚拟机中,对象在内存中的存储布局分为 3 块区域:
对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)
参考链接: https://stackoverflow.com/questions/26357186/what-is-in-java-object-header
1.对象头由一个标记字(mark word)和一个类指针(klass pointer)组成。
2.标记字一个word大小:32位架构4字节,也就是32位。
64位架构8字节,也就是64位。
类指针也是一个word大小: 在32位架构下,即4字节。
64位架构下,8字节,但如果堆地址可以用这4个字节编码,也可以用4个字节。
3.这种优化被称为“compressed oops”,就是我们通常说的压缩指针,你可以使用UseCompressedOops选项来控制它。
4.mark word 作用:
a.一个是偏向锁定, HotSpot可以通过它实现高效的锁定。
b.GC期间:
设置前向指针,存储对象年龄
c.存储对象的标识哈希码hashcode
2.垃圾回收过程中颜色指针的应用
颜色指针在垃圾回收过程里的使用简单说明:
a.初始化:整个内存空间的地址视图被设置为Remapped。
b.标记阶段:第一次进入标记阶段时视图为M0,如果对象被GC标记线程或者应用线程访问过,那么就将对象的地址视图从Remapped调整为M0。
所以,在标记阶段结束之后,对象的地址要么是M0视图,要么是Remapped。如果对象的地址是M0视图,那么说明对象是活跃的;
如果对象的地址是Remapped视图,说明对象是不活跃的。
在标记阶段存在两个地址视图M0和M1,上面的过程显示只用了一个地址视图。之所以设计成两个,是为了区别前一次标记和当前标记。
也即,第二次进入并发标记阶段后,地址视图调整为M1,而非M0。
c.并发转移:标记结束后就进入转移阶段,此时地址视图再次被设置为Remapped。如果对象被GC转移线程或者应用线程访问过,
那么就将对象的地址视图从M0调整为Remapped。
将对象设置为已标记,传统的垃圾回收器需要进行一次内存访问,并将对象存活信息放在对象头中;而在ZGC中,只需要设置指针地址的第42~45位即可,
并且因为是寄存器访问,所以速度比访问内存更快。具体如何使用,会在zgc垃圾回收的过程里再详细描述。