Sunday, October 30, 2011

Notes on tuning JVM

Notes from a talk about tuning the JVM by Attila Szegedi, Twitter.

Know the problem and options

Use these option to get to know whether GC happens often:

-verbosegc
-XX:+PrintDCDetails
-XX:+PrintHeapAtGC
-XX:+PrintTenuringDistribution

More eden size is always better. Old generation collectors:

  1. Throughput collectors:
        -XX:+UseSerialGC
        -XX:+UseParallelGC
        -XX:+UseParallelOldGC
  2. Low-pause collectors:
        -XX:+UseConcMarkSweepGC
        -XX:+UseG1GC
  3. Adaptive threshold collectors:
        -XX:+UseAdaptiveSizePolicy (with throughput collectors only)
        -XX:MaxGCPauseMillis=100 (ms)
        -XX:GCTimeRatio=19 (GC time : running time ratio)
  4. If all fails, us concurrent mark-and-sweep, collects all the time. Hence, having extra CPU can help avoid stop-the-world latency!
        -XX:InitiatingOccupyFraction (set to 75-80, triggers GC)

Fat data

Data might be taking too much memory.

Object headers

Object header = 2 machine words = 128 bits on 64 bit machine = 16 bytes

Similarly, Array headers take 24 bytes.

  • new java.lang.Object() takes 16 bytes
  • new byte[0] takes 24 bytes

Padding:

In 8 bytes blocks. Happens for each subtyping.

class A { byte x; };
class B extends A { byte y; }
  • new A() takes 24 bytes (add 1 byte -> get 7 more bytes for padding)
  • new B() takes 32 bytes (same here)

No inline structures

class C { Object obj = new Object(); }
  • new C() takes 40 bytes.
  • 2 objects handlers and 1 pointer (w/ padding) = 16 + 16 + 8 = 40

Compressed pointers

-XX:+UseCompressedOops

Pointers become 4 bytes long and can be used below 32 Gb heap size. On by default from JDK 6, update 21.

Vally in performance in going from 30 Gb heap to 40 Gb, as points grow from 4 to 8 bytes.

Primitive wrappers

Happens without knowing (say, in Scala 2.7.7, Scala 2.7.8 fixed it):

  • Seq[Int] stores java.lang.Integer => needs 24 + 32 * length bytes
  • Array[Int] stores int => needs 24 + 4 * length bytes

Moral: Surprises exist. Profile everything.

Thread locals hurt

Threads don't die (pools). Just create new objects.

Summary

UncompressedCompressed32-bit
Pointer 8 4 4
Object header 16 12* 8
Array Header 24 16 12
Superclass pad 8 4 4
  • Compressed memory: Object can have 4 bytes of fields and still take only 16 bytes.
There are a lot of other interesting things he talked about as well, like Apache Thrift, Guava MapMaker libraries, etc.

~ musically_ut

No comments: