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

Aleksey Shipilev aleksey.shipilev at oracle.com
Wed Sep 4 02:42:01 PDT 2013


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:
  $ ~/Install/jdk8b104/bin/java -version
   java version "1.8.0-ea"
   Java(TM) SE Runtime Environment (build 1.8.0-ea-b104)
   Java HotSpot(TM) 64-Bit Server VM (build 25.0-b46, mixed mode)

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!

This does not reproduce with either:
  -XX:+UseSerialGC
  -XX:+UseG1GC
  -XX:+UseConcMarkSweepGC

This does reproduce reliably with either:
  -XX:+UseParallelGC
  -XX:+UseParallelOldGC

I tried to quantify the performance impact of this, and there are some
minuscule differences, mostly tolerated by the CPU caching working well
in both forward and backward traversal orders. The performance
difference seem to enforce the hypothesis there the additional memory
pressure while walking array laid out by parallel GC.

Is this the (known) bug?

-Aleksey.


More information about the hotspot-gc-dev mailing list