Dettagli su mark word dell'intestazione dell'oggetto java


Sto studiando la composizione dell'intestazione dell'oggetto java.

Trovato alcuni documenti e alcuni problemi interessanti.

Sotto la vm a 64 bit, la testa dell'oggetto predefinita è la seguente (perché {[2] } è attivata per impostazione predefinita)

|--------------------------------------------------------------------------------------------------------------|--------------------|
|                                            Object Header (96 bits)                                           |        State       |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                  Mark Word (64 bits)                           |    Klass Word (32 bits)     |                    |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
| unused:25 | identity_hashcode:31 | cms_free:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Normal       |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
| thread:54 |       epoch:2        | cms_free:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Biased       |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                         ptr_to_lock_record                            | lock:2 |    OOP to metadata object   | Lightweight Locked |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                     ptr_to_heavyweight_monitor                        | lock:2 |    OOP to metadata object   | Heavyweight Locked |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                                                       | lock:2 |    OOP to metadata object   |    Marked for GC   |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|

Se UseCompressedOops è disattivato, l'intestazione dell'oggetto è simile a questa:

|------------------------------------------------------------------------------------------------------------|--------------------|
|                                            Object Header (128 bits)                                        |        State       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                  Mark Word (64 bits)                         |    Klass Word (64 bits)     |                    |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
| unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Normal       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
| thread:54 |       epoch:2        | unused:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Biased       |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                       ptr_to_lock_record:62                         | lock:2 |    OOP to metadata object   | Lightweight Locked |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                     ptr_to_heavyweight_monitor:62                   | lock:2 |    OOP to metadata object   | Heavyweight Locked |
|------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                                                     | lock:2 |    OOP to metadata object   |    Marked for GC   |
|------------------------------------------------------------------------------|-----------------------------|--------------------|

E il codice sorgente C++ su markword è qui: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/oops/markOop.hpp

Ho una domanda:

Perché un bit è passato da inutilizzato a cms_free quando la compressione del puntatore è abilitata?

Sospetto che abbia qualcosa a che fare con il garbage collector CMS, ma non so cosa faccia.

E quando controllo le informazioni rilevanti dell'intestazione dell'oggetto (incluse le due tabelle sopra), la maggior parte di esse menzionava markOop.hpp file, ma ha introdotto solo il blocco correlato. Ignora cms_free, narrowOop, promo_bits, PromotedObjec menzionato in markOop.hpp che informazioni importanti, quindi sono curioso di questa parte.

Author: Holger, 2020-04-02

1 answers

Quando si usano puntatori piatti, i bit più bassi dei puntatori di indirizzo sono sempre zero a causa dell'allineamento e consentono di contrassegnare uno stato speciale scrivendone uno in questi bit. Quindi il CMS imposta il bit più basso del puntatore klass su uno quando vuole indicare che il particolare pezzo di memoria non è un oggetto (più), ma memoria libera.

Ma la funzione puntatore compresso utilizza la stessa proprietà per indirizzare più memoria tramite un puntatore a 32 bit spostando a destra l'indirizzo e non lasciando inutilizzato bit inferiori. Pertanto, il CMS deve memorizzare questo bit da qualche altra parte, cioè il cms_free_bit in questione.

Fonte: concurrentMarkSweepGeneration.cpp :

// 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
 5
Author: Holger, 2020-04-06 12:34:26