java-perf-tuning

Java Performance Tuning

This repo holds:

=======

=======

Memory Model

Portability vs Native Code Generation

The JVM provides runtime services such as memory management, garbage collection, and security checks during program execution & hardware abstraction and hence called virtual machine. Compiled C++ programs produce standalone executables that do not rely on a separate runtime environment. They interact directly with the underlying operating system and hardware without an intermediary layer like a virtual machine.

GC

Need to prevent segmentation fault and memory leak issues

System.gc() == Runtime.getRuntime().gc() (Above calls induce full GC, which may suspend threads, use -XX:+DisableExplicitGC and prefer never to call GC explicitly)

#

Objects are copied to S0 from Eden so that fragments are not created and Eden can start fresh altogether.

#

Memory Sizes and Flags

Using CLI, pass as java -Xms2560m MyCls (sets the initial heap size to 2560 megabytes)

Logs

Can heapdump in VisualVM to store heap info at a moment.

How GC Works?

Types of GC

HotSpot JVM provides:

  1. Serial GC: does mark-sweep and compaction. Only one thread
  2. Parallel GC: Used to be JVM default till Java8. Uses multiple threads -XX:ParallelGCThreads=<N>, select -XX:+UseParallelGC. It uses Stop-the-World strategy
  3. Concurrent Mark and Sweep (CMS): Does not use stop the world strategy but stops threads, if changes happen in heap
  4. G1: Now default GC from Java9. Designed for multiprocessor, large memory systems. Divides heap in equal size spaces and firstly reclaims spaces which are mostly empty. It suspends threads only briefly

How to make object ready for GC

  1. Create local var
  2. Nullify ref
  3. Reassign ref
  4. Create anonymous ref

Loading Activities

How class is loaded

Linking

Types of loaders

  1. Bootstrap - Written in C/C++ (Native). Loads rt.jar classes like java.lang, java.util, java.io and java.net (rt = runtime)
  2. Extension - loads extensions (additional APIs, libraries, and tools that are not part of the standard Java distribution but are commonly used in Java development) from ext folder
  3. Application or System

Parent to Child relationship: Bootstrap -> Extension -> Application/System
Delegation happens to parent and if parent is not able to load, it delegates back to child (as shown below) Otherwise ClassNotFoundException is thrown:

Multithreading

ThreadLocal in Java provides thread-local variables. These are variables that are only visible and accessible to the thread that sets them. Each thread has its own, independently initialized copy of the variable.

Tips

  1. Do not create object unless needed. And create object just before its usage
  2. Make methods static which do not use instance data, so that they can be called as Cls.method() and no need to create obj of class (Object creation is heavy process, need to go up hierarchy to call all ctors)
  3. Use right GC for your app - can have stop-the-world event? Want to use multiprocessor?
  4. For one time use, create anonymous objects
public class AnonymousObjectExample {
    public static void main(String[] args) {
        // Creating an anonymous object of the Person class
        new Person().introduce(); // Anonymous object calling the method directly
    }
}

class Person {
    public void introduce() {
        System.out.println("Hi, I am Gaurav's anonymous person!");
    }
}
  1. Release variable when no longer needed by setting to null
  2. Use try-with-resource AutoCloseable interface resource management utility. So no need to close resources by making finally block
  3. Static fields are GC roots, which means they are never garbage-collected. So, never use mutable static fields — use only constants.
  4. Use helper clases - At times it is possible to have a class with lot of static variables and methods. Split these classes into smaller classes so that only those classes which are being used are loaded in the memory
  5. Use StringBuilder if possible. Also avoid wrapper and BigInteger (or similar) classes if possible
  6. Since recursion can create lot of local vars, do not use recursion, if loop is feasible
  7. Optimize SQL queries - use indexes, use conditional retrievals, try avoiding too many joins, use joins over subqueries
  8. If multiple checks on String validations, instead of if-else, use regex
  9. JPA vs JDBC - JDBC is lower layer to manually interact with DB. JPA’s implementation like Hibernate provides more OO way and caching, lazy loading and auto schema generation capabilities.