java.lang.Object 中的 'shadow$_klass_' 和 'shadow$_monitor_' 变量是什么?

在最新的 Android 更新 (SDK 21) 中,似乎添加了两个新变量:java.lang.Object

private transient Class<?> shadow$_klass_;
private transient int shadow$_monitor_;

我注意到它被简要地用于:shadow$_monitor_hashCode()

public int hashCode() {
    int lockWord = shadow$_monitor_;
    final int lockWordMask = 0xC0000000;  // Top 2 bits.
    final int lockWordStateHash = 0x80000000;  // Top 2 bits are value 2 (kStateHash).
    if ((lockWord & lockWordMask) == lockWordStateHash) {
        return lockWord & ~lockWordMask;
    }
    return System.identityHashCode(this);
}

但除此之外,没有提及它们。它们是否与ART中的GC有某种关系?还是某种原生的东西?


答案 1

它们确实与GC有关。它们似乎是为了支持布鲁克斯指针而添加的。我在这里找到了一些关于布鲁克斯指针的信息:

这个想法是堆上的每个对象都有一个额外的引用字段。此字段要么指向对象本身,要么在将对象复制到新位置后立即指向该新位置。这将使我们能够与突变体线程同时撤出对象

请特别参阅以下两个提交:

libcore: a7c69f785f7d1b07b7da22cfb9150c584ee143f4

art: 9d04a20bde1b1855cefc64aebc1a44e253b1a13b


答案 2

这些是与JDK中的Shenandoah垃圾收集相关的类。

OpenJDK Serial,Parallel,Concurrent Mark Sweep和G1中有4个较旧的GC。然而,这些问题的问题在于它们至少需要压缩整个旧堆至少一次,如果堆很大,这将非常重。Shenandoah 设计为 100Gb+ 堆提供 <10 毫秒的暂停。

这是通过使用基于Brooks Pointers的Forward Pointers来实现的。这些转发指针是。shadow_$klassshadow$_monitor

Shenandoah GC 中的主要思想是,它允许应用程序线程在压缩期间移动堆中的对象(将引用的对象移动到更好的位置)时与堆中的对象进行交互,从而消除了“停止世界”的需要。

看看另一个SO答案:对象类中的布鲁克斯指针


推荐