GC Allocation Failures
When you are running a Java application, if you add these JVM arguments, it would log the Java Garbage collection details to a log file.
-Xloggc:gc_memory_logs.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
Typically these logs would looks like this.
1.703: [GC [PSYoungGen: 132096K->16897K(153600K)] 132096K->16905K(503296K), 0.0171210 secs] [Times: user=0.05 sys=0.01, real=0.01 secs]
3.162: [GC [PSYoungGen: 148993K->21488K(153600K)] 149001K->22069K(503296K), 0.0203860 secs] [Times: user=0.04 sys=0.00, real=0.02 secs]
In some cases, you may have come across the following log, which as it appears seems to be erroneous.
13.874: [GC (Allocation Failure) [PSYoungGen: 1048576K->174561K(1223168K)] 1188537K->329386K(4019712K), 0.1936445 secs] [Times: user=0.18 sys=0.09, real=0.19 secs]
This ‘Allocation failure’ log is not an error but is a totally normal case in JVM. This is a typical GC event which causes the Java Garbage Collection process to get triggered. Garbage Collection removes dead objects, compact reclaimed memory and thus helps in freeing up memory for new object allocations.
From my post, I hope to provide further insights to the Allocation failure GC event.
The Java Heap Space can be divided into 2 generations as follows.
- Young generation
- Old generation
The Young Generation is where all new objects are allocated. A young generation is garbage collected very quickly and frequently removing all the dead and de-referenced objects. Some survived objects from this collection are aged and are moved to the old generation gradually.
young generation is further divided into following 3 types.
- Survivor space From
- Survivor space To
- Eden Space : When object created using new keyword memory is initially allocated on this space.
- _Survivor Space _(To/From): This is the space which contains objects which have survived after java garbage collection is performed in Eden space.
The Old Generation is used to store long surviving objects. Typically, a threshold is set for young generation object and when that age is reached, the object gets moved to the old generation. This means that the objects have survived multiple numbers of garbage collections in both Eden and survivor spaces. This is also referred as Tenured space.
In addition to that, there is also Permanent generation which contains metadata required by the JVM, describing the classes and methods used in the Java application. The permanent generation is populated by the JVM at runtime based on classes in use by the application. This has been replaced with Metaspace since Java 8.
When the eden space of young generation fills up, this triggers a minor garbage collection. This is also known as Young generation GC. In Minor GC, the garbage collector is running on the young generation only.
A Minor GC moves live objects from eden to survivor ‘from’ space. It also empties survivor ‘from’ by moving young live objects to ‘to’. Furthermore it promotes old live objects to tenured generation.
When tenured space is full, a full GC event will get triggered. This event is also called a _major garbage collection. _A full GC will follow a 3 step process (Mark Sweep Compact) to deallocate dead objects and defragment freespace.
Allocation Failure happens when there isn’t enough free space to create new objects in Young generation. Allocation failures triggers minor GC (to do a minor collection) to free up space in the heap for the allocation request. With minor GC, space is freed for the new allocation to to be made in the young generation. Therefore Allocation failure log is simply a Java logging indicating that it ran out of heap space and it triggered a garbage collection.
A minor GC will further move long-surviving objects to old generation during the process to free up the required memory. In this case if the tenured space is already full, this will trigger a Full GC (Allocation Failure) event. A full GC allocation failure will trigger a full GC cycle to kick in. A full GC will remove all dead and unreferenced objects in the tenured space. However if full GC is not able to evacuate required heap space for the requested allocation, then the JVM will crash with an
OutOfMemoryError: Java heap space error.