SlideShare a Scribd company logo
Java Performance Tuning Minh Hoang TO Portal Team
Agenda Performance Measure   JRE Customization  Programming Tips Reading Suggestions
Performance Measure
Performance Measure Performance Analytical Tools Determine problem Attack performance problem
Performance Analytical Tools JDK tools: JVisualVM (since Java 6), JConsole Commercial tools: JProfiler
Determine problem Factor to improve? Time or Memory Quantitative analysis to encircle the root causes Use tools to localize memory leak, method call overhead Theoretical argument servers for first-step analysis, but tools provide most convincing information
Attack performance problem Improve execution environment Examine programming aspect
JRE Customization
JRE Customization JVM Options Customize Garbage Collection Frequently used JVM options
JVM Options JAVA_HOME/java JAVA_HOME/java -X
Customize Garbage Collection JAVA_HOME/java -X   -Xnoclassgc -Xincgc
Frequently used JVM options Heap size options -Xms -Xmx Permanent Generation options -XX:MaxPermSize Class sharing -Xshare
Programming Tips
Programming Tips Object Creation String Collection Framework Java IO and NIO (for next time) Concurrency
Object Creation Object scope final   modifier Interaction with Garbage Collector
Object Scope String wideScope;  for(int  i =0; i <10000000; i++) {   wideScope = “” + i; } vs for(int i = 0; i < 10000000; i++) { String narrowScope = “” + i; }
Heap space is divided into  Young Generation  and  Old Generation  spaces JAVA_HOME/jconsole Garbage Collector has best performance on  Young Generation Object with narrow scope has more chance to stay in  Young Generation
Final modifier Protect variable against reference reassignment (non-reflect code) final SafeObject safeObject = new SafeObject(); safeObject = null; // compilation error Modularize code with anonymous class final String displayString = “Hello”; Runnable runnable = new Runnable(){ public void run() { System.out.println(displayString); } };
Final modifier Affect of  final  at execution Look at my  IntelliJ IDEA 10
Interaction with Garbage Collector GC   (Garbage Collector) reclaims memory occupied by unreferenced object TestObject strongReference = new TestObject();  //variable strongReference //points to memory cells at 0xXXXX  strongReference = null; //no reference to cells 0xXXXX System.gc();  //Run the GC GC  handles  SoftReference ,  WeakReference  and  PhantomReference  exceptionally JavaDoc from package  java.lang.ref
//Object is allocated at 0xXXXX TestObject  strongReference = new TestObject();  SoftReference<TestObject> softReference = new SoftReference<TestObject>(strongReference);  //Object stored at 0xXXX is reachable from softReference strongReference = null;  //No more strong reference to object  Object stored at 0xXXXX is softly reachable from softReference, but  automatically cleaned  by  GC  when  there is lack of memory
Code from LazyList class of GateIn private static class Batch { private final Reference<Object[]> elements; private Batch(Object[] elements) { this.elements = new SoftReference<Object[]>(elements); } }
String String Thread-safe, expensive handling methods StringBuffer Thread-safe, much faster than  String StringBuilder Not thread-safe, slightly faster than  StringBuffer
String s = new String(); for(int i = 0; i < 10000; i++){ s += “a”; } VS StringBuffer buffer = new StringBuffer(); for(int i = 0; i < 10000; i++){ buffer.append(“a”); } VS StringBuilder builder = new StringBuilder(); for(int i = 0; i < 10000; i++){ builder.append(“a”); }
Collection Framework Random Access vs Sequential Initial allocation HashMap vs TreeMap WeakHashMap
Random Access vs Sequential ArrayList<E> access element: O(1) add element at the end: O(1) or O(n)   sort element: O(n.logn)  (sort with Collections.sort()) LinkedList<E> access element: O(n) add element at both ends: O(1) sort element: O(n.logn) + O(n)  (sort with Collections.sort())
Initial Allocation Code snippet recurring in eXo products List<String> list = new ArrayList<String>(3); Why hard-coded size? Is it better than List<String> list = new LinkedList<String>();
HashMap vs TreeMap HashMap<K,V> fetch <K,V> entry: O(1) put <K,V> entry: O(n) in worst case sort <K,V> entries based on key: Not supported TreeMap<K,V> fetch <K,V> entry: O(1) Put <K,V> entry: O(n) in worst case support sorting entries based on key
WeakHashMap private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> { private V value; private final int hash; private Entry<K,V> next; … . }
Java IO and NIO In many cases: gainOf(  improve_on_programming_logic  )  <<<< gainOf(  improve_on_input_output ) Java coder should have knowledge on Java NIO
Concurrency Concurrency concepts Intrinsic lock volatile  keyword Lock & Lock-free
Concurrency concepts Atomicity Code executing on a thread is not inteferenced with other threads Ex:  Code incrementing a counter Visibility Change  on shared object is visible to multiple threads Ex:  Flag variable
Atomicity  yields  Visibility Atomicity  problems are more complex than  Visibility  ones Figure out your concurrency problem ( Atomicity  or  Visibility ) before typing  synchronized
Intrinsic lock -  synchronized Ensure   Atomicity Overhead of synchronized   Double-checked pattern 'intrinsic lock extension' in  java.util.concurrent.locks
private int counter; private void increaseCounter(){ counter++;} private synchronized void increaseCounterUsingIntrinsicLock(){ counter++;} public static void main(String[] args) {   int n = 100000;   //Print time to call increaseCounter  n times  //Print time to call  increaseCounterUsingIntrinsicLock n times }
Double-checked pattern synchronized( locked_object ) {   if( flag_variable ){ //do something } } VS if( flag_variable ){   synchronized( locked_object ) {   if( flag_variable ){ //do something }   } }
Double-checked reduces the scope of  synchronized  block Useful in concurrent initialization problem Requires  Visibility  on  flag_variable
Code from RootContainer class in eXo Kernel public static RootContainer getInstance() { RootContainer result = singleton_; if (result == null) { synchronized (RootContainer.class)   {….}   }  }
Code from Component class in WebUI Framework public Event getUIComponentEventConfig(String eventName) throws Exception { if(eventMap == null) { synchronized(this) { if(eventMap == null) {…}   } } }
Volatile keyword Ensure  Visibility Work only with atomic operations Usage in double-checked pattern 'volatile extension' in  java.util.concurrent.atomic
private volatile long counter; private void nonAtomicOperation(){ counter++;} private void atomicOperation(){ counter = 281283;}
Usage in double-checked pattern Java Memory Model permutes execution order in multi-thread world (JVM Specification) Visibility  on flag_variable is mandatory to double-checked pattern volatile boolean flag_variable;  //Assumed the type is boolean //Double-checked block
Lock & Lock-free Lock Package  java.util.concurrent.locks Lock-free Package  java.util.concurrent.atomic
Reading Suggestions
Java Concurrency in Practice – Brian Goetz Java IO  Java NIO
Thank you!

More Related Content

Java Performance Tuning

  • 1. Java Performance Tuning Minh Hoang TO Portal Team
  • 2. Agenda Performance Measure JRE Customization Programming Tips Reading Suggestions
  • 4. Performance Measure Performance Analytical Tools Determine problem Attack performance problem
  • 5. Performance Analytical Tools JDK tools: JVisualVM (since Java 6), JConsole Commercial tools: JProfiler
  • 6. Determine problem Factor to improve? Time or Memory Quantitative analysis to encircle the root causes Use tools to localize memory leak, method call overhead Theoretical argument servers for first-step analysis, but tools provide most convincing information
  • 7. Attack performance problem Improve execution environment Examine programming aspect
  • 9. JRE Customization JVM Options Customize Garbage Collection Frequently used JVM options
  • 10. JVM Options JAVA_HOME/java JAVA_HOME/java -X
  • 11. Customize Garbage Collection JAVA_HOME/java -X -Xnoclassgc -Xincgc
  • 12. Frequently used JVM options Heap size options -Xms -Xmx Permanent Generation options -XX:MaxPermSize Class sharing -Xshare
  • 14. Programming Tips Object Creation String Collection Framework Java IO and NIO (for next time) Concurrency
  • 15. Object Creation Object scope final modifier Interaction with Garbage Collector
  • 16. Object Scope String wideScope; for(int i =0; i <10000000; i++) { wideScope = “” + i; } vs for(int i = 0; i < 10000000; i++) { String narrowScope = “” + i; }
  • 17. Heap space is divided into Young Generation and Old Generation spaces JAVA_HOME/jconsole Garbage Collector has best performance on Young Generation Object with narrow scope has more chance to stay in Young Generation
  • 18. Final modifier Protect variable against reference reassignment (non-reflect code) final SafeObject safeObject = new SafeObject(); safeObject = null; // compilation error Modularize code with anonymous class final String displayString = “Hello”; Runnable runnable = new Runnable(){ public void run() { System.out.println(displayString); } };
  • 19. Final modifier Affect of final at execution Look at my IntelliJ IDEA 10
  • 20. Interaction with Garbage Collector GC (Garbage Collector) reclaims memory occupied by unreferenced object TestObject strongReference = new TestObject(); //variable strongReference //points to memory cells at 0xXXXX strongReference = null; //no reference to cells 0xXXXX System.gc(); //Run the GC GC handles SoftReference , WeakReference and PhantomReference exceptionally JavaDoc from package java.lang.ref
  • 21. //Object is allocated at 0xXXXX TestObject strongReference = new TestObject(); SoftReference<TestObject> softReference = new SoftReference<TestObject>(strongReference); //Object stored at 0xXXX is reachable from softReference strongReference = null; //No more strong reference to object Object stored at 0xXXXX is softly reachable from softReference, but automatically cleaned by GC when there is lack of memory
  • 22. Code from LazyList class of GateIn private static class Batch { private final Reference<Object[]> elements; private Batch(Object[] elements) { this.elements = new SoftReference<Object[]>(elements); } }
  • 23. String String Thread-safe, expensive handling methods StringBuffer Thread-safe, much faster than String StringBuilder Not thread-safe, slightly faster than StringBuffer
  • 24. String s = new String(); for(int i = 0; i < 10000; i++){ s += “a”; } VS StringBuffer buffer = new StringBuffer(); for(int i = 0; i < 10000; i++){ buffer.append(“a”); } VS StringBuilder builder = new StringBuilder(); for(int i = 0; i < 10000; i++){ builder.append(“a”); }
  • 25. Collection Framework Random Access vs Sequential Initial allocation HashMap vs TreeMap WeakHashMap
  • 26. Random Access vs Sequential ArrayList<E> access element: O(1) add element at the end: O(1) or O(n) sort element: O(n.logn) (sort with Collections.sort()) LinkedList<E> access element: O(n) add element at both ends: O(1) sort element: O(n.logn) + O(n) (sort with Collections.sort())
  • 27. Initial Allocation Code snippet recurring in eXo products List<String> list = new ArrayList<String>(3); Why hard-coded size? Is it better than List<String> list = new LinkedList<String>();
  • 28. HashMap vs TreeMap HashMap<K,V> fetch <K,V> entry: O(1) put <K,V> entry: O(n) in worst case sort <K,V> entries based on key: Not supported TreeMap<K,V> fetch <K,V> entry: O(1) Put <K,V> entry: O(n) in worst case support sorting entries based on key
  • 29. WeakHashMap private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> { private V value; private final int hash; private Entry<K,V> next; … . }
  • 30. Java IO and NIO In many cases: gainOf( improve_on_programming_logic ) <<<< gainOf( improve_on_input_output ) Java coder should have knowledge on Java NIO
  • 31. Concurrency Concurrency concepts Intrinsic lock volatile keyword Lock & Lock-free
  • 32. Concurrency concepts Atomicity Code executing on a thread is not inteferenced with other threads Ex: Code incrementing a counter Visibility Change on shared object is visible to multiple threads Ex: Flag variable
  • 33. Atomicity yields Visibility Atomicity problems are more complex than Visibility ones Figure out your concurrency problem ( Atomicity or Visibility ) before typing synchronized
  • 34. Intrinsic lock - synchronized Ensure Atomicity Overhead of synchronized Double-checked pattern 'intrinsic lock extension' in java.util.concurrent.locks
  • 35. private int counter; private void increaseCounter(){ counter++;} private synchronized void increaseCounterUsingIntrinsicLock(){ counter++;} public static void main(String[] args) { int n = 100000; //Print time to call increaseCounter n times //Print time to call increaseCounterUsingIntrinsicLock n times }
  • 36. Double-checked pattern synchronized( locked_object ) { if( flag_variable ){ //do something } } VS if( flag_variable ){ synchronized( locked_object ) { if( flag_variable ){ //do something } } }
  • 37. Double-checked reduces the scope of synchronized block Useful in concurrent initialization problem Requires Visibility on flag_variable
  • 38. Code from RootContainer class in eXo Kernel public static RootContainer getInstance() { RootContainer result = singleton_; if (result == null) { synchronized (RootContainer.class) {….} } }
  • 39. Code from Component class in WebUI Framework public Event getUIComponentEventConfig(String eventName) throws Exception { if(eventMap == null) { synchronized(this) { if(eventMap == null) {…} } } }
  • 40. Volatile keyword Ensure Visibility Work only with atomic operations Usage in double-checked pattern 'volatile extension' in java.util.concurrent.atomic
  • 41. private volatile long counter; private void nonAtomicOperation(){ counter++;} private void atomicOperation(){ counter = 281283;}
  • 42. Usage in double-checked pattern Java Memory Model permutes execution order in multi-thread world (JVM Specification) Visibility on flag_variable is mandatory to double-checked pattern volatile boolean flag_variable; //Assumed the type is boolean //Double-checked block
  • 43. Lock & Lock-free Lock Package java.util.concurrent.locks Lock-free Package java.util.concurrent.atomic
  • 45. Java Concurrency in Practice – Brian Goetz Java IO Java NIO