stu*_*ent 5 c++ java jvm jvm-hotspot hotspot
我正在研究java对象头的组成。
发现了一些文档和一些有趣的问题。
64位vm下,默认对象头如下(因为UseCompressedOops默认是开启的)
|------------------------------------------------- -------------------------------------------------- -----------|--------------------| | 对象头(96 位)| 状态 | |------------------------------------------------- -------------------------------|------------------- -----------|--------------------| | 标记字(64 位) | 类字(32 位) | | |------------------------------------------------- -------------------------------|------------------- -----------|--------------------| | 未使用:25 | identity_hashcode:31 | cms_free:1 | 年龄:4 | 偏向锁:1 | 锁:2 | OOP 到元数据对象 | 正常 | |------------------------------------------------- -------------------------------|------------------- -----------|--------------------| | 线程:54 | 时代:2 | cms_free:1 | 年龄:4 | 偏向锁:1 | 锁:2 | OOP 到元数据对象 | 有偏见 | |------------------------------------------------- -------------------------------|------------------- -----------|--------------------| | ptr_to_lock_record | 锁:2 | OOP 到元数据对象 | 轻量级锁定 | |------------------------------------------------- -------------------------------|------------------- -----------|--------------------| | ptr_to_heavyweight_monitor | 锁:2 | OOP 到元数据对象 | 重量级锁定 | |------------------------------------------------- -------------------------------|------------------- -----------|--------------------| | | 锁:2 | OOP 到元数据对象 | 标记为 GC | |------------------------------------------------- -------------------------------|------------------- -----------|--------------------|
如果UseCompressedOops关闭,对象头长这个样子?
|------------------------------------------------- -------------------------------------------------- ---------|--------------------| | 对象头(128 位)| 状态 | |------------------------------------------------- -----------------------------|-------------------- ---------|--------------------| | 标记字(64 位) | 类字(64 位) | | |------------------------------------------------- -----------------------------|-------------------- ---------|--------------------| | 未使用:25 | identity_hashcode:31 | 未使用:1 | 年龄:4 | 偏向锁:1 | 锁:2 | OOP 到元数据对象 | 正常 | |------------------------------------------------- -----------------------------|-------------------- ---------|--------------------| | 线程:54 | 时代:2 | 未使用:1 | 年龄:4 | 偏向锁:1 | 锁:2 | OOP 到元数据对象 | 有偏见 | |------------------------------------------------- -----------------------------|-------------------- ---------|--------------------| | ptr_to_lock_record:62 | 锁:2 | OOP 到元数据对象 | 轻量级锁定 | |------------------------------------------------- -----------------------------|-------------------- ---------|--------------------| | ptr_to_heavyweight_monitor:62 | 锁:2 | OOP 到元数据对象 | 重量级锁定 | |------------------------------------------------- -----------------------------|-------------------- ---------|--------------------| | | 锁:2 | OOP 到元数据对象 | 标记为 GC | |------------------------------------------------- -----------------------------|-------------------- ---------|--------------------|
还有关于markword的C++源代码在这里吗? http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/oops/markOop.hpp
我有个问题?
启用指针压缩时,为什么一位从未使用变为 cms_free?
我怀疑它与 CMS 垃圾收集器有关,但我不知道它的作用。
而当我查看对象头的相关信息(包括上面的两个表)时,大部分都提到了markOop.hpp文件,但只介绍了与Lock相关的内容。忽略markOop.hpp那个重要信息中提到的cms_free、narrowOop、promo_bits、PromotedObjec ,所以我对这部分很好奇。
使用平面指针时,地址指针的最低位由于对齐而始终为零,并允许通过将 1 写入这些位来标记特殊状态。因此,当 CMSklass想要表示特定内存块不是对象(不再)而是空闲内存时,它将指针的最低位设置为 1。
但是压缩指针功能利用相同的属性通过 32 位指针通过右移地址而不留下未使用的低位来寻址更多内存。因此,CMS 必须将此位存储在其他地方,即所cms_free_bit讨论的位置。
来源:concurrentMarkSweepGeneration.cpp:
Run Code Online (Sandbox Code Playgroud)// A block of storage in the CMS generation is always in // one of three states. A free block (FREE), an allocated // object (OBJECT) whose size() method reports the correct size, // and an intermediate state (TRANSIENT) in which its size cannot // be accurately determined. // STATE IDENTIFICATION: (32 bit and 64 bit w/o COOPS) // ----------------------------------------------------- // FREE: klass_word & 1 == 1; mark_word holds block size // // OBJECT: klass_word installed; klass_word != 0 && klass_word & 1 == 0; // obj->size() computes correct size // // TRANSIENT: klass_word == 0; size is indeterminate until we become an OBJECT // // STATE IDENTIFICATION: (64 bit+COOPS) // ------------------------------------ // FREE: mark_word & CMS_FREE_BIT == 1; mark_word & ~CMS_FREE_BIT gives block_size // // OBJECT: klass_word installed; klass_word != 0; // obj->size() computes correct size // // TRANSIENT: klass_word == 0; size is indeterminate until we become an OBJECT
| 归档时间: |
|
| 查看次数: |
473 次 |
| 最近记录: |