60

In the latest Android update (SDK 21), it appears that two new variables have been added to java.lang.Object:

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

I notice that shadow$_monitor_ is briefly used in 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);
}

But otherwise there are no references to them. Are they somehow related to GC in ART? Or some sort of native stuff?

Lii
  • 11,553
  • 8
  • 64
  • 88
Tspoon
  • 3,670
  • 1
  • 26
  • 33
  • 2
    I don't have an answer, however some of these links helped me understand what might be happening. Just posting them incase they help someone else! http://stackoverflow.com/questions/3362303/whats-a-monitor , http://stackoverflow.com/questions/16721021/what-is-klass-klassklass , http://stackoverflow.com/questions/1092099/what-is-variable-shadowing-used-for-in-a-java-class , http://stackoverflow.com/questions/910374/why-does-java-have-transient-variables – Kevvvvyp Nov 18 '14 at 15:36
  • @Tspoon, what is the significance of these values or how are these values used?Any idea? – Diffy May 29 '15 at 15:26

2 Answers2

28

They are indeed connected to GC. They seem to have been added in order to support Brooks pointers. I found some information on Brooks pointers here:

The idea is that each object on the heap has one additional reference field. This field either points to the object itself, or, as soon as the object gets copied to a new location, to that new location. This will enable us to evacuate objects concurrently with mutator threads

See especially these two commits:

libcore: a7c69f785f7d1b07b7da22cfb9150c584ee143f4

art: 9d04a20bde1b1855cefc64aebc1a44e253b1a13b

Petter
  • 4,053
  • 27
  • 33
  • how is the calculation of hashcode done here? Why is the calculation done on shadow$_monitor_? – Diffy May 29 '15 at 15:24
  • 1
    When an object is relocated by the garbage collector, its original hashcode has to be stored somewhere in case it is used again. The obvious way to implement this would be to add a 32 bit field to the object header to hold the hashcode. But that would add a 1 word overhead to every object, and would waste space in the most common case ... where an Object's hashCode method is not called. For more details visit this thread https://stackoverflow.com/a/3796963 – Mahendra Chhimwal May 30 '18 at 16:18
  • That is interesting, but doesn't that render WeakReferences useless? – Matt J. Oct 12 '19 at 01:04
1

These are classes related to Shenandoah Garbage Collection in JDK.

There are 4 older GC in OpenJDK Serial,Parallel,Concurrent Mark Sweep, & G1. Yet the problem with these lie in the fact that they need to compact the entire old heap atleast once & if the heap is large, this will be very heavy. Shenandoah is designed with <10ms pauses for 100Gb+ heaps.

This is achieved by using Forwarding Pointers based on Brooks Pointers.The shadow_$klass & shadow$_monitor are these forwarding pointers.

The primary idea in Shenandoah GC, is that it allows application threads to interact with objects in heap while they're being moved around during compacting (moving referenced objects to a better location), removing the need to "stop-the-world"

Look at this other SO answer: Brooks Pointer in Object class

Chandrahas Aroori
  • 955
  • 2
  • 14
  • 27