Skip to content

2. Java GC Notes

Rajendra Prasad Reddy Penumalli edited this page Jan 5, 2020 · 14 revisions

Java Object Life Cycle

objectlifecycle

Dog Object Life Cycle


    Dog dog = new Dog(); // creation of Object Dog

    ....
    //Creation of Dog Objects
    Dog dog = new Dog();
    Dog dog2 = new Dog();
    dog = null;// Object refereed by dog directly goes to Unreachable state
    }

JVM vs JRE

Java Runtime Memory

Java Runtime Memory split into two parts:

  • Stack (holds data like method local variables,callstack,and Thread-related metadata. smaller size ~1MB).
  • Heap

Max Heap Allowed

  • For a 64-bit JVM running in a 64-bit OS on a 64-bit machine, is there any limit besides the theoretical limit of 2^64 bytes or 16 exabytes
  • For 32 bit JVM running in a 32-bit OS, in terms of unsigned integer and they think maximum addressable memory (size of address bus) for 32 bit architecture is 4G GB (But here OS takes major role and Windows takes more than 2 GB)

Simple JVM Memory Model

HotSpotJVM

Java Memory Architecture (Java Memory Model)

JavaMemoryModel

Different Regions in JVM Memory

  • 5 regions:
    1. Eden
    2. Survivor 1
    3. Survivor 2
    4. Old (or Tenured) Generation
    5. Perm Generation (until Java 7). Since Java 8, Perm Generation has been replaced with Metaspace.
  • Note: Eden, Survivor 1 and Survivor 2 are collectively called the Young Generation.

Survivor Ratio Sizing

  • The SurvivorRatio parameter controls the size of the two survivor spaces. For example,
  • For example,-XX:SurvivorRatio=6 sets the ratio between each survivor space and eden to be 1:6, each survivor space will be one eighth of the young generation.
  • The default for Solaris is 32. If survivor spaces are too small, copying collection overflows directly into the old generation. If survivor spaces are too large, they will be empty. At each GC, the JVM determines the number of times an object can be copied before it is tenured, called the tenure threshold.
  • This threshold is chosen to keep the survivor space half full.
  • Use the option -XX:+PrintTenuringDistribution to show the threshold and ages of the objects in the new generation. It is useful for observing the lifetime distribution of an application.

Purpose of Each Region in Java Memory

  • Eden Generation: When an object is newly constructed it’s created in the Young Generation. In most of the applications, most of the objects are short-lived objects. i.e. they will die soon. Thus they will be collected as garbage within the Young Generation itself.

  • Survivor: Objects that survive Minor GC are not directly promoted to the Old Generation. They are kept in the Survivor region for a certain number of Minor GC collections. Only if they survive certain number of Minor GC collections can they be promoted to the Old Generation.

  • Old (or Tenured) Generation: Certain objects tend to be long-lived. Example: Application Context, HTTP Sessions, Caches, Connection Pools, etc. Those long-lived objects are promoted to old generation.

  • Perm Generation: This is the location where JVM objects such as Classes, Methods, String Interns, etc. are created.

Metaspace: Starting with Java 8, the perm generation has been replaced with Metaspace for performance reasons.

Three types of GC's:

  1. Minor GC
  2. Major GC
  3. Full GC
  • Minor GC: It’s also called as Scavenge GC. This is the GC which collects garbage from the Young Generation.
  • Major GC: This GC collects garbage from the Old Generation
  • Full GC: This GC collects garbage from all regions i.e. Young, Old, Perm, Metaspace.

When Major or Full GC run all application threads are paused. It’s called a stop-the-world event. In Minor GCs, stop-the-world events occurs, but only momentarily

Performance goals in regards of Garbage Collection:

  1. Latency
  2. Throughput
  3. Capacity

JVM Behavior in Under Different Memory Pressures:

  1. Fast memory usage growth.
  2. Medium memory usage growth.
  3. Slow memory usage growth.

Java Memory Pools

HotSpot JVM includes three types of garbage collectors:

  1. Serial Collector
  2. Parallel Collector (also known as the throughput collector)
  3. CMS (The Mostly Concurrent Collectors)
  4. G1 GC
  • Serial: The serial collector uses a single thread to perform all garbage collection work. It is best-suited to single processor machines, because it cannot take advantage of multiprocessor hardware. It’s enabled with the option -XX:+UseSerialGC.

  • Parallel: The parallel collector (also known as the throughput collector) performs minor collections in parallel, which can significantly reduce garbage collection overhead. It is intended for applications with medium-sized to large-sized data sets that are run on multiprocessors or multithreaded hardware. It’s enabled with the option -XX:+UseParallelGC.

  • CMS: The mostly concurrent collector performs most of its work concurrently (for example, while the application is still running) to keep garbage collection pauses short. It is designed for applications with medium-sized to large-sized data sets in which response time is more important than overall throughput because the techniques used to minimize pauses can reduce application performance. It’s enabled with the option -XX:+UseConcMarkSweepGC.

  • G1: G1 is the latest garbage collector, targeted for multi-processor machines with large memories. It meets garbage collection (GC) pause time goals with high probability, while achieving high throughput. Whole-heap operations, such as global marking, are performed concurrently with the application threads. It’s enabled with the option -XX:+UseG1GC.

  • G1 uses concurrent and parallel phases to achieve its target pause time and to maintain good throughput

Which GC Algorithem to Use

WhichGC2Use

Other JVM garbage collectors are:

  1. C4 (Azul Zing JVM: Continuous Concurrent Compacting Collector (C4))
  2. Shenandoah
  3. Balanced (IBM J9 JVM)

Five widely used garbage collector solutions for OpenJDK:

  1. G1
  2. Parallel (also known as the throughput collector)
  3. ConcMarkSweep (CMS)
  4. Serial
  5. Shenandoah
  • Shenandoah: Shenandoah is the latest garbage collector,which reduces GC pause times by doing evacuation work concurrently with the running Java threads. Pause times with Shenandoah are independent of heap size, meaning you will have the same consistent pause times whether your heap is 200 MB or 200 GB. Shenandoah GC will initially be marked as an experimental feature and thus require -XX:+UnlockExperimentalVMOptions in addition to -XX:+UseShenandoahGC.

JVM Options by GC Type

Option_In_GC_Types

Three main objectives of garbage collection :

  1. Mark: Finding objects which are no longer used.
  2. Sweep: Freeing up the memory after those objects.
  3. Compact: Compacting the heap

Not all the collectors perform those operations in the same way.

Marking Objects

Java-GC-mark-and-sweep

Memory Compaction (After Sweeping)

fragmented-vs-compacted-heap

Comparision of Collectors

Comparision_of_collectors

GCTypes

GenerationalGC

GenerationalGC

JVM Arguments

How to Pass arguments for JVM

java -jar -DmyProp="Hello World" myProgram.jar

Distinct categories (-X,-XX,-D) of JVM arguments :

  1. Standard Options (-D but not only): These are the most commonly used options that are supported by all implementations of the JVM. You use -D to specify System properties but most of them don't have any prefix :-verbose, -showversion, and so for...
  2. Non-Standard Options (prefixed with -X) These options are general purpose options that are specific to the Java HotSpot Virtual Machine. For example : -Xmssize, -Xmxsize
  3. Advanced Runtime Options (prefixed with -XX) These options control the runtime behavior of the Java HotSpot VM.
  4. Advanced JIT Compiler Options (prefixed with -XX) These options control the dynamic just-in-time (JIT) compilation performed by the Java HotSpot VM.
  5. Advanced Serviceability Options (prefixed with -XX) These options provide the ability to gather system information and perform extensive debugging.
  6. Advanced Garbage Collection Options (prefixed with -XX) These options control how garbage collection (GC) is performed by the Java HotSpot VM.

Java <= 7

 -server
 -Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]
 -XX:PermSize=<perm gen size>[g|m|k] -XX:MaxPermSize=<perm gen size>[g|m|k]
 -Xmn<young size>[g|m|k]
 -XX:SurvivorRatio=<ratio>
 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
 -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
 -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
 -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
 -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
 -Dsun.net.inetaddr.ttl=<TTL in seconds>
 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
 -Djava.rmi.server.hostname=<external IP>
 -Dcom.sun.management.jmxremote.port=<port> 
 -Dcom.sun.management.jmxremote.authenticate=false 
 -Dcom.sun.management.jmxremote.ssl=false

Java >= 8

   -server
   -Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]
   -XX:MaxMetaspaceSize=<metaspace size>[g|m|k]
   -Xmn<young size>[g|m|k]
   -XX:SurvivorRatio=<ratio>
   -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
   -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
   -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
   -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
   -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
   -Dsun.net.inetaddr.ttl=<TTL in seconds>
   -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
   -Djava.rmi.server.hostname=<external IP>
   -Dcom.sun.management.jmxremote.port=<port> 
   -Dcom.sun.management.jmxremote.authenticate=false 
   -Dcom.sun.management.jmxremote.ssl=false

Difference between jdk7 na jdk8

Analyzing GC Tuning Results By Looking At GC Log (Prioritised List)

  • Full GC execution time
  • Minor GC execution time
  • Full GC execution interval
  • Minor GC execution interval
  • Entire Full GC execution time
  • Entire Minor GC execution time
  • Entire GC execution time
  • Full GC execution times
  • Minor GC execution timesl

Common Debugging Utilities for Memory Leaks

  • Using the jhat Utility
  • Creating a Heap Dump
  • Obtaining a Heap Histogram on a Running Process
  • Obtaining a Heap Histogram at OutOfMemoryError
  • Monitoring the Number of Objects Pending Finalization
  • Third Party Memory Debuggers

Common strategies for Debugging Memory Leak Issues

  • Identify Symptoms
  • Enable Verbose Garbage Collection
  • Enable Profiling
  • Analyze the Trace

Java Memeory Exceptions Reasons

  1. lang.OutOfMemoryError: Java heap space
  2. lang.OutOfMemoryError: PermGen space
  3. lang.OutOfMemoryError: Kill process or sacrifice child
  4. lang.OutOfMemoryError: GC overhead limit exceeded
  5. lang.OutOfMemoryError: Metaspace
  6. lang.OutOfMemoryError: request bytes. Out of swap space?
  7. lang.OutOfMemoryError: unable to create new native thread
  8. lang.OutOfMemoryError: Requested array size exceeds VM limit

Java Performance Problems

  1. DB Pool Configuration
  2. Memeory
  3. GC Related
  4. GC Algorithems: Using Correct GC Algorithems
  5. Memory Leak :Profiling Code
  6. Concurrency :Profiling Code

Concurrency Means?

  • Concurrency occurs when several computations are executed at the same time.
  • Java uses synchronization and locks to manage multi threading.
  • But synchronization can cause thread deadlocks, gridlocks and thread pool size issues.

Keywords:

  • STW -Stop the World
  • Latency
  • Throughput
  • Thread
  • Stack
  • Heap
  • GC Log
  • GC Pauses
  • GC Algorithems
  • GC Root
  • Thread Dump
  • Heap Dump
  • JMX

References:

Sample Applications

Clone this wiki locally