Parallel GC and array object layout: way off the base and laid out in reverse?

Thomas Schatzl thomas.schatzl at oracle.com
Wed Sep 4 03:19:19 PDT 2013


Hi Aleksey,

On Wed, 2013-09-04 at 13:42 +0400, Aleksey Shipilev wrote:
> Hi there, GC gurus!
> 
> While ramping up another OpenJDK tool, I bumped into the interesting GC
> behavior w.r.t. object layout. I have minimized this into test:
>  http://cr.openjdk.java.net/~shade/scratch/ArrayLayoutTest.java
> 
> This is the Java version I'm using:
>[...]
> The test allocates Integer[10] and fills it with integers. "Unit" is
> some fixed bytes count, subject to 32/64-bit and COOPs settings. The
> peculiar behavior as follows:
> 
> $ java -XX:+UseParallelGC ArrayLayoutTest
> Before the GC:
> array is at 4120951026 (0 units off base)
>   object is at 4120951033, 7 units off base, toString = 0
>   object is at 4120951035, 9 units off base, toString = 1
>   object is at 4120951037, 11 units off base, toString = 2
>   object is at 4120951039, 13 units off base, toString = 3
>   object is at 4120951041, 15 units off base, toString = 4
>   object is at 4120951043, 17 units off base, toString = 5
>   object is at 4120951045, 19 units off base, toString = 6
>   object is at 4120951047, 21 units off base, toString = 7
>   object is at 4120951049, 23 units off base, toString = 8
>   object is at 4120951051, 25 units off base, toString = 9
> 
> After the GC:
> array is at 3772780866 (0 units off base)
>   object is at 3772784336, 3470 units off base, toString = 0
>   object is at 3772784334, 3468 units off base, toString = 1
>   object is at 3772784332, 3466 units off base, toString = 2
>   object is at 3772784330, 3464 units off base, toString = 3
>   object is at 3772784328, 3462 units off base, toString = 4
>   object is at 3772784326, 3460 units off base, toString = 5
>   object is at 3772784324, 3458 units off base, toString = 6
>   object is at 3772784322, 3456 units off base, toString = 7
>   object is at 3772784320, 3454 units off base, toString = 8
>   object is at 3772784318, 3452 units off base, toString = 9
> 
> Note we have the dense packing for young objects, and after we promote
> (note the base address change), suddenly we have two artifacts:
>   a) the array elements are way off the array itself
>   b) the array elements are laid out in *reverse* order!

  no, you are tripping over a (well?) known peculiarity of
java.lang.Integer in the HotSpot VM.

All Integer instances in byte range (-128..127) are often replaced by
singletons of that value. I.e. there is some internal array of these
Integers that is used instead of separate instances.

Depending on how the GC relocates these singleton Integer instances, you
will get different values. I.e. when running this program, I sometimes
even got negative offsets.

Use values outside of this range to get useful results, i.e. arr[c] =
new Integer(c+128). Or strings.
 
Hth,
Thomas




More information about the hotspot-gc-dev mailing list