美团面试官问我: ZGC 的 Z 是什么意思 (2)

这个架构被称为 SMP (Symmetric Multi-Processor),因为任一个 CPU 对内存的访问速度是一致的,不用考虑不同内存地址之间的差异,所以也称一致内存访问(Uniform Memory Access, UMA )。

这个核心越加越多,渐渐的总线和北桥就成为瓶颈,那不能够啊,于是就想了个办法。

把 CPU 和内存集成到一个单元上,这个就是非一致内存访问 (Non-Uniform Memory Access,NUMA)。

美团面试官问我: ZGC 的 Z 是什么意思

简单的说就是把内存分一分,每个 CPU 访问自己的本地的内存比较快,访问别人的远程内存就比较慢。

当然也可以多个 CPU 享受一块内存或者多块,如下图所示:

美团面试官问我: ZGC 的 Z 是什么意思

但是因为内存被切分为本地内存和远程内存,当某个模块比较“热”的时候,就可能产生本地内存爆满,而远程内存都很空闲的情况。

比如 64G 内存一分为二,模块一的内存用了31G,而另一个模块的内存用了5G,且模块一只能用本地内存,这就产生了内存不平衡问题。

如果有些策略规定不能访问远程内存的时候,就会出现明明还有很多内存却产生 SWAP(将部分内存置换到硬盘中) 的情况。

即使允许访问远程内存那也比本地内存访问速率相差较大,这是使用 NUMA 需要考虑的问题。

ZGC 对 NUMA 的支持是小分区分配时会优先从本地内存分配,如果本地内存不足则从远程内存分配。

对于中、大分区的话就交由操作系统决定。

上述做法的原因是生成的绝大部分都是小分区对象,因此优先本地分配速度较快,而且也不易造成内存不平衡的情况。

而中、大分区对象较大,如果都从本地分配则可能会导致内存不平衡的情况。

Using colored pointers

染色指针其实就是从 64 位的指针中,拿几位来标识对象此时的情况,分别表示 Marked0、Marked1、Remapped、Finalizable。

美团面试官问我: ZGC 的 Z 是什么意思

我们再来看下源码中的注释,非常的清晰直观:

美团面试官问我: ZGC 的 Z 是什么意思

0-41 这 42 位就是正常的地址,所以说 ZGC 最大支持 4TB (理论上可以16TB)的内存,因为就 42 位用来表示地址。

也因此 ZGC 不支持 32 位指针,也不支持指针压缩。

然后用 42-45 位来作为标志位,其实不管这个标志位是啥指向的都是同一个对象。

这是通过多重映射来做的,很简单就是多个虚拟地址指向同一个物理地址,不过对象地址是 0001.... 还是0010....还是0100..... 对应的都是同一个物理地址即可。

具体这几个标记位怎么用的,待下文回收流程分析再解释。

不过这里先提个问题,为什么就支持 4TB,不是还有很多位没用吗

首先 X86_64 的地址总线只有 48 条 ,所以最多其实只能用 48 位,指令集是 64 位没错,但是硬件层面就支持 48 位。

因为基本上没有多少系统支持这么大的内存,那支持 64 位就没必要了,所以就支持到 48 位。

那现在对象地址就用了 42 位,染色指针用了 4 位,不是还有 2 位可以用吗?

是的,理论上可以支持 16 TB,不过暂时认为 4TB 够了,所以暂做保留,仅此而已没啥特别的含义。

Using load barriers

在 CMS 和 G1 中都用到了写屏障,而 ZGC 用到了读屏障。

写屏障是在对象引用赋值时候的 AOP,而读屏障是在读取引用时的 AOP。

比如 Object a = obj.foo;,这个过程就会触发读屏障。

也正是用了读屏障,ZGC 可以并发转移对象,而 G1 用的是写屏障,所以转移对象时候只能 STW。

简单的说就是 GC 线程转移对象之后,应用线程读取对象时,可以利用读屏障通过指针上的标志来判断对象是否被转移。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwyyd.html