java.lang.Object 中的“shadow$_klass_”和“shadow$_monitor_”变量是啥?
Posted
技术标签:
【中文标题】java.lang.Object 中的“shadow$_klass_”和“shadow$_monitor_”变量是啥?【英文标题】:What are the 'shadow$_klass_' and 'shadow$_monitor_' variables for in java.lang.Object?java.lang.Object 中的“shadow$_klass_”和“shadow$_monitor_”变量是什么? 【发布时间】:2021-10-09 19:34:04 【问题描述】:在最新的 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 有关吗?还是某种原生的东西?
【问题讨论】:
我没有答案,但是其中一些链接帮助我了解了可能发生的情况。只是张贴他们以防他们帮助别人! ***.com/questions/3362303/whats-a-monitor,***.com/questions/16721021/what-is-klass-klassklass,***.com/questions/1092099/…,***.com/questions/910374/… @Tspoon,这些值的意义是什么或者这些值是如何使用的?知道吗? 【参考方案1】:它们确实连接到 GC。它们似乎是为了支持布鲁克斯的指针而添加的。我找到了一些关于布鲁克斯指针here的信息:
这个想法是堆上的每个对象都有一个额外的引用字段。该字段要么指向对象本身,要么一旦对象被复制到新位置,就指向该新位置。这将使我们能够与 mutator 线程同时撤离对象
尤其是这两个提交:
libcore: a7c69f785f7d1b07b7da22cfb9150c584ee143f4
art: 9d04a20bde1b1855cefc64aebc1a44e253b1a13b
【讨论】:
这里hashcode的计算是怎么做的?为什么要在 shadow$_monitor_ 上进行计算? 当一个对象被垃圾收集器重新定位时,它的原始哈希码必须存储在某个地方以防再次使用。实现这一点的明显方法是在对象头中添加一个 32 位字段来保存哈希码。但这会给每个对象增加 1 个字的开销,并且在最常见的情况下会浪费空间……在不调用对象的 hashCode 方法的情况下。有关更多详细信息,请访问此线程***.com/a/3796963 这很有趣,但这不是让 WeakReferences 没用吗?【参考方案2】:这些是与 JDK 中的 Shenandoah Garbage Collection 相关的类。
OpenJDK Serial、Parallel、Concurrent Mark Sweep 和 G1 中有 4 个较旧的 GC。然而,这些问题在于它们需要至少压缩整个旧堆一次,如果堆很大,这将非常重。 Shenandoah 针对 100Gb+ 堆设计了
这是通过使用基于布鲁克斯指针的转发指针来实现的。shadow_$klass
和shadow$_monitor
是这些转发指针。
Shenandoah GC 的主要思想是,它允许应用程序线程与堆中的对象进行交互,同时它们在压缩期间被移动(将引用的对象移动到更好的位置),无需“停止-世界”
看看这个其他的答案:***s Pointer in Object class
【讨论】:
以上是关于java.lang.Object 中的“shadow$_klass_”和“shadow$_monitor_”变量是啥?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 java.lang.Object 中的 finalize() 方法是“受保护的”?
java.lang.Object 中的“shadow$_klass_”和“shadow$_monitor_”变量是啥?
Eclipse 中的 Java 项目:无法解析 java.lang.Object 类型。它是从所需的 .class 文件中间接引用的
如何修复CrudRepository.save(java.lang.Object)是springboot中的无法访问方法?