250 likes | 291 Views
Explore the intricacies of JVM internals, including bytecode, optimizations, garbage collection, and runtime operations. Learn about compile-time vs. run-time optimizations, memory management patterns, and advanced techniques like common sub-expression elimination and loop unrolling.
E N D
JVM Internals • Douglas Q. Hawkins
JVM Internals • Bytecode • Garbage Collection • Optimizations • Compile Time • Run Time
Java Bytecode • Stack Based • Local Variable Space Local Variables Operand Stack 7 + 10 3
Operation Types • Load and Store • Arithmetic and Logic • Type Conversion • Control Transfer • Object Creation and Manipulation • Operand Stack • Method Invocation
Garbage Collection • Generational Garbage Collection • Segmented into Young, Old, and Permanent Generations • Types of Collectors • Parallel - across multiple threads • Concurrent - while program runs
Garbage Collection Pattern • Minor • Major • Major Again - for objects with finalize • Soft References • Major • Major Again - for objects with finalize • Throw OutOfMemoryError
Optimizations • Just In Time Compilation • Purely Interpreted • Ahead of Time Compilation • Almost No Compile Time Optimization • Most Optimizations are Runtime
Is This Optimized? double sumU = 0, sumV = 0; for ( int i = 0; i < 100; ++i ) { Vector2D vector = new Vector2D( i, i ); synchronized ( vector ) { sumU += vector.getU(); sumV += vector.getV(); } } How many...? Loop Iterations 100 0 Heap Allocations 100 0 Method Invocations 200 0 Lock Operations 100 0
Common Sub-Expression Elimination int x = a + b; int y = a + b; int tmp = a + b; int x = tmp; int y = tmp;
Array Bounds Check Elimination int[] nums = ... for ( int i = 0; i < nums.length; ++i ) { System.out.println( “nums[“ + i + “]=” + nums[ i ] ); } int[] nums = ... for ( int i = 0; i < nums.length; ++i ) { if ( i < 0 || i >= nums.length ) { throw new ArrayIndexOutOfBoundsException(); } System.out.println( “nums[“ + i + “]=” + nums[ i ] ); }
Loop Invariant Hoisting for ( int i = 0; i < nums.length; ++i ) { ... } int length = nums.length; for ( int i = 0; i < length; ++i ) { ... }
Loop Unrolling int sum = 0; for ( int i = 0; i < 10; ++i ) { sum += i; } int sum = 0; sum += 1; ... sum += 9;
Method Inlining Vector vector = ... double magnitude = vector.magnitude(); static always Vector vector = ... double magnitude = Math.sqrt( vector.u*vector.u + vector.v*vector.v ); final always private always virtual often Vector vector = ... double magnitude; if ( vector instance of Vector2D ) { magnitude = Math.sqrt( vector.u*vector.u + vector.v*vector.v ); } else { magnitude = vector.magnitude(); } reflective sometimes dynamic often
Lock Coarsening StringBuffer buffer = ... buffer.append( “Hello” ); buffer.append( name ); buffer.append( “\n” ); StringBuffer buffer = ... lock( buffer ); buffer.append( “Hello” ); unlock( buffer ); lock( buffer ); buffer.append( name ); unlock( buffer ); lock( buffer ); buffer.append( “\n” ); unlock( buffer ); StringBuffer buffer = ... lock( buffer ); buffer.append( “Hello” ); buffer.append( name ); buffer.append( “\n” ); unlock( buffer );
Other Lock Optimizations • Biased Locking • Adaptive Locking - Thread sleep vs. Spin lock
Escape Analysis Point p1 = new Point(x1, y1), p2 = new Point(x2, y2); synchronized ( p1 ) { synchronized ( p2 ) { double dx = p1.getX() - p2.getX(); double dy = p1.getY() - p2.getY(); double distance = Math.sqrt( dx*dx + dy*dy ); } } double dx = x1 - x2; double dx = y1 - y2; double distance = Math.sqrt( dx*dx + dy*dy );
Resources • Brian Goetz • Developer Works Articles • Tony Printezis • Garbage Collection in the Java HotSpot Virtual Machine - http://www.devx.com/Java/Article/21977 • Java Specialist Newsletter - http://www.javaspecialists.eu/ • http://java.sun.com/javase/6/docs/technotes/guides/vm/cms-6.html • http://java.sun.com/docs/hotspot/gc1.4.2/faq.html • http://www.fasterj.com/articles/G1.html • http://www.informit.com/guides/content.aspx?g=java&seqNum=27