2. Java Process Life Cycle
Parse the command line options
Establish the heap sizes and the compiler
type (client or server)
Establishes the environment variables
Creates the VM using JNI_CreateJavaVM
Find the main class
The java main method is invoked using
CallStaticVoidMethod
DestroyJVM
www.qunar.com
3. VM Class Loading
When does it happen
• bytecode resolution
• Class.forName(), classLoader.loadClass(),
reflection APIs, and JNI_FindClass
• VM startup
• java.lang.String
• java.lang.System
• java.lang.Thread, java.lang.ThreadGroup
• java.lang.reflect.Method
• java.lang.ref.Finalizer
• java.lang.Class
www.qunar.com
5. VM Class Loading
Class loaders are organized in a tree
Loading Order
• looks up in its own cache, if found, return
• If fails, delegates the request to the parent, if
found, return
• If fails, loads the class itself and searches its
own path, if found, return
• If fails, a ClassNotFoundException is thrown
www.qunar.com
8. JVM Memory Layout
For One Thread
• PC register
• The address of a JVM instruction being executed
now
• JVM stack
• jinfo -flag ThreadStackSize {PID}
• Native method stack
Shared By All Threads
• Method area (PermGen)
• Runtime constant pool
• Included in Method Area
• Heap
• A target of garbage collection
www.qunar.com
9. JVM Memory Layout
Computing The Size of An Object
(X86_64)
• Arrays of boolean, byte, char, short, int: 2 * 8
(Object header) + 4 (length-field) +
sizeof(primitiveType) * length -> align result
up to a multiple of 8
• Arrays of objects: 2 * 8 (Object header) + 4
(length-field) + 4 (dead space due to
alignment restrictions) + 8 * length
• Arrays of longs and doubles: 2 * 8 (Object
header) + 4 (length-field) + 4 (dead space due
to alignment restrictions) + 8 * length
www.qunar.com
10. JVM Memory Layout
Computing The Size of An Object
• java.lang.Object: 2 * 8 (Object header)
• other objects: sizeofSuperClass + 8 *
nrOfLongDoubleAndObjectFields + 4 *
nrOfntAndFloatFields + 2 *
nrOfShortAndCharFields + 1 *
nrOfByteAndBooleanFields -> align result up
to a multiple of 8
www.qunar.com
13. Structure of Heap
Eden are space there objects are
allocated
Survivor spaces are used to receive object
during young (or minor GC)
Tenured space is for long lived objects
Permanent space is the Method Area and
Runtime Constant Pool mentioned earlier
www.qunar.com
14. Hotspot GC Options
Serial generational collector (-XX:+UseSerialGC).
Parallel for young space, serial for old space
generational collector (-XX:+UseParallelGC).
Parallel young and old space generational collector (-
XX:+UseParallelOldGC).
Concurrent mark sweep with serial young space
collector (-XX:+UseConcMarkSweepGC
–XX:-UseParNewGC).
Concurrent mark sweep with parallel young space
collector (-XX:+UseConcMarkSweepGC –
XX:+UseParNewGC).
G1 garbage collector (-XX:+UseG1GC, not covered in
this talk)
www.qunar.com
15. Generational GC
Young GC
• Write Barrier
• Always Stop-The-World
• Parallel
• ParNew
Full GC
• Parallel Mark Sweep
• Concurrent Mark Sweep
www.qunar.com
16. Young GC
What Triggers Young GC
• New objects are allocated in Eden
• Once Eden becomes full Young GC is triggered
Goal of Young GC
• To clear fresh garbage in Eden space
What does Young GC
• live objects are copied to another space, and then
whole space is marked as free memory
How to find live objects
• find all root references (Root references for young GC
are references from stack and all references from old
space)
www.qunar.com
17. Young GC
Dirty Cards Write Barrier
• prevent scaning all objects in old gen to find
root references
• card page size is 512 bytes
• the card table is implemented as a simple
array of bytes
• each 512 byte page of memory has
associated byte in card table
• each time when program modifies reference
in memory, it should mark modified memory
page as dirty
www.qunar.com
19. Young GC
While JVM is updating references to relocated object, memory
pages get marked again, so we can be sure that on next young
GC only dirty pages has references to young space
www.qunar.com
20. Young GC
Object Promotion
• -XX:+AlwaysTenure makes JVM to promote objects
directly to old space instead of survivor space
• once survivor space is full, all remaining live object
are relocated directly to old space
• if object has survived certain number of young space
collections, it will be promoted to old space
• –XX:MaxTenuringThreshold
– e.g., -XX:MaxTenuringThreshold=16 # Copy
object between survivor space at most 16 times
• –XX:TargetSurvivorRatio
– e.g., -XX:TargetSurvivorRatio=90 # Keep each
survivor space about 90% full
www.qunar.com
21. Young GC
Time of young GC
• Tstack_scan – can be considered application specific
constant
• Tcard_scan – is proportional to size of old space.
Literally, JVM have to check single byte of table for
each 512 bytes of heap (e.g. 8G of heap -> 16m to
scan)
• Told_scan – is proportional to number of dirty cards
in old space at the moment of young GC.
www.qunar.com
22. Full GC
What triggers full gc
• Old Generation being full or promotion failure
• Calls to
• System.gc()
• Runtime.gc()
• through distributed „RMI‟
• If Xms and Xmx have different values and the
old gen grows
• if PermSize and MaxPermSize have different
values and the Permanent Space grows
www.qunar.com
23. Full GC
Mark-Sweep Model
• Starting with the root objects
• Objects represented by all active stack frames and
all the static variables
• Marks each node it visits
• Objects not marked are reclaimed and
returned to the free list
• an array of lists that chained together free heap
chunks of predetermined size
www.qunar.com
25. Full GC
CMS
• -XX: +UseConcMarkSweepGC
• triggered when amount of free memory in old space falls below
certain threshold
• -XX:+UseCMSInitiatingOccupancyOnly
• -XX:CMSInitiatingOccupancyFraction=70 (this will force CMS
cycle to start when more than 70% of old space is used)
• Yields lower full gc pause time and better responsiveness of
your application
• Falls back to STW full gc when:
• CMS is not fast enough for dealing with garbage
• Collection cycle has been started too late
• fragmentation of old space
www.qunar.com
26. Full GC
CMS
• Initial mark – STW, collecting root references
• Concurrent mark – traverses through object graph in
tenured space marking living objects
• Concurrent pre clean - try to account references
changed during previous mark phase, to reduce time
of STW remark phase
• Remark – STW, to account references which have
been changed during concurrent mark phase
• Concurrent sweep
• Concurrent reset
www.qunar.com
28. CompressedOops
What is an object instance
• a block of memory set aside on the heap
• contain instance data and other meta
information
• represented in hotpot by the oopDesc data-
structure
• an object is referenced via an oop:
• a native memory address when running on 32-bit
architecture
• An 32-bit index into the heap with -
XX:+UseCompressedOops on 64-bit architecture
www.qunar.com
31. jinfo
Prints Java configuration information for a
given Java process or core file or a remote
debug server.
Common Usage
• sudo -u tomcat /home/q/java/default/bin/jinfo -
flag ThreadStackSize ${pid}
• sudo -u tomcat /home/q/java/default/bin/jinfo -
flag UseCompressedOops ${pid}
• sudo -u tomcat /home/q/java/default/bin/jinfo –
sysprops ${pid}
www.qunar.com
32. Jstack usage
Prints Java stack traces of Java threads
for a given Java process or core file or a
remote debug server
Common Usage
• sudo -u tomcat /home/q/java/default/bin/jstack
${pid} | less
www.qunar.com
34. Jstack explanation
Thread Information
• Thread name
• When using Java.lang.Thread class to generate a thread, the
thread will be named Thread-(Number), whereas when using
java.util.concurrent.ThreadFactory class, it will be named
pool-(number)-thread-(number)
• Priority
• the priority of the threads.
• Thread ID
• the unique ID for the threads
• Thread status
• the status of the threads
• Thread callstack
• The call stack information of the threads
www.qunar.com
35. Jstack explanation
Thread ID
• Each java thread is mapped one-on-one to os
thread
• Nid is the hexadecimal representation of
native thread id
• [root@l-bnb3.dev.cn6 ~]# ps -eLf | grep $(printf
"%dn" 0x4454)
www.qunar.com
37. Jstack explanation
NEW: created but has not been processed yet.
RUNNABLE: The thread is occupying the CPU
and processing a task.
BLOCKED: waiting for a different thread to
release its lock in order to get the monitor lock.
WAITING: The thread is waiting indefinitely by
using a wait, join or park method.
TIMED_WAITING: The thread is waiting by
using a sleep, wait, join or park method for up to
a specified waiting time.
www.qunar.com
38. jstat
Displays performance statistics for an
instrumented HotSpot Java virtual
machine (JVM)
Common Usage
• sudo -u tomcat /home/q/java/default/bin/jstat -
gcutil ${pid}1000 1000
www.qunar.com
39. Jmap & mat
Prints shared object memory maps or
heap memory details of a given process or
core file or a remote debug server.
Common Usage
• sudo -u tomcat /home/q/java/default/bin/jmap -
histo:live ${pid} | less
• sudo -u tomcat /home/q/java/default/bin/jmap -heap
${pid} | less
• sudo -u tomcat /home/q/java/default/bin/jmap -
dump:live,format=b,file=/home/q/memdump/memMap
.20121030.hprof ${pid}
www.qunar.com
40. Jmap & mat
Analyze hprof dump file with MAT
• Eclipse mat 1.2.0 is required, otherwise you
will get incorrect statistics about memory
occupation due to the mishandling of
CompressedOops in 1.1.0
• Key Concepts
• Incoming/outgoing references
• Shallow/retained heap
www.qunar.com
41. Jvm core dump analysis
the first thing is:
Don't Panic
try following the steps below:
1. log in as root
2. executing ulimit -aH, check whether the
“core file sizes” is specified as unlimited, if
not, executing ulimit -c unlimited
www.qunar.com
42. Jvm core dump analysis
check whether there's enough space left in your current work dir
4. running the java process again using the command obtained from
the previous "ps aux|grep java"
5. waiting for the java process crashing again
6. collecting the core dump file from the current work dir
7. doing like that:
• gdb /home/q/java/jdk1.6.0_20/bin/java core.9537
8. there are ways to obtain java-related information from core dump
file:
• obtaining java memory dump: /home/q/java/jdk1.6.0_20/bin/jmap
-dump:format=b,file=dump.1013.hprof
/home/q/java/jdk1.6.0_20/jre/bin/java core.26408
• obtaining jstack info: /home/q/java/jdk1.6.0_20/bin/jstack
/home/q/java/jdk1.6.0_20/bin/java core.26408 >
core_stack_1013.txt
www.qunar.com