-
Notifications
You must be signed in to change notification settings - Fork 0
Garbage Collector & Memory Leaks
Garbage Collection is the process of freeing space in the heap for allocation of new objects. One of the best feature of Java is the automatic garbage collection. Garbage Collector is the program running in the background that looks into all the objects in the memory and find out objects that are not referenced by any part of the program. All these unreferenced objects are deleted and space is reclaimed for allocation to other objects. One of the basic way of garbage collection involves three steps:
- Marking : This is the first step where garbage collector identifies which objects are in use and which ones are not in use
- Normal Deletion : Garbage collector removes the unused objects and reclaims the free space to be allocated to other objects
- Deletion with compacting : For better performance, after deleting unused objects, all the survived objects can be moved to be together. This will increase the performance of allocation of memory to newer objects.
JVM uses the mark and sweep garbage collection model for performing garbage collection of the whole heap. A mark and sweep garbage collection consists of two phases, the mark phase and the sweep phase.
During the mark phase, all the objects that are reachable from Java threads, native handlers and other root sources are marked as alive, as well as the objects that are reachable from these objects and so forth. This process identifies and marks all objects that are still used, and the rest can be considered garbage.
During the sweep phase, the heap is traversed to find the gaps between the live objects. These gaps are recorded in a free list and are made available for new object allocation.
There are five types of garbage collection types that we can use in our applications. We just need to use JVM switch to enable the garbage collection strategy for the application.
1. Serial GC (-XX:+UseSerialGC): Serial GC uses the simple mark-sweep-compact approach for young and old generations garbage collection i.e Minor and Major GC. Serial GC is useful in client-machines such as our simple stand alone applications and machines with smaller CPU. It is good for small applications with low memory footprint.
2. Parallel GC (-XX:+UseParallelGC): Parallel GC is same as Serial GC except that is spawns N threads for young generation garbage collection where N is the number of CPU cores in the system. We can control the number of threads using -XX:ParallelGCThreads=n JVM option. Parallel Garbage Collector is also called throughput collector because it uses multiple CPUs to speed up the GC performance. Parallel GC uses single thread for Old Generation garbage collection.
3.Parallel Old GC (-XX:+UseParallelOldGC): This is same as Parallel GC except that it uses multiple threads for both Young Generation and Old Generation garbage collection.
4. Concurrent Mark Sweep (CMS) Collector (-XX:+UseConcMarkSweepGC): CMS Collector is also referred as concurrent low pause collector. It does the garbage collection for Old generation. CMS collector tries to minimize the pauses due to garbage collection by doing most of the garbage collection work concurrently with the application threads. CMS collector on young generation uses the same algorithm as that of the parallel collector. This garbage collector is suitable for responsive applications where we can’t afford longer pause times. We can limit the number of threads in CMS collector using -XX:ParallelCMSThreads=n JVM option.
5. G1 Garbage Collector (-XX:+UseG1GC): The Garbage First or G1 garbage collector is available from Java 7 and it’s long term goal is to replace the CMS collector. The G1 collector is a parallel, concurrent, and incrementally compacting low-pause garbage collector. Garbage First Collector doesn’t work like other collectors and there is no concept of Young and Old generation space. It divides the heap space into multiple equal-sized heap regions. When a garbage collection is invoked, it first collects the region with lesser live data, hence “Garbage First”. You can find more details about it at Garbage-First Collector Oracle Documentation.
Most Common Memory issues are
- ** Exception in thread "main":** java.lang.OutOfMemoryError: Java heap space. This does not necessarily imply a memory leak — as it could be due to lesser space configured for the heap. Otherwise, in a long-lived application it could be due to an unintentional reference being mentioned to heap objects (memory leak). Even the APIs that are called by the application could be holding references to objects that are unwarranted. Also, in applications that make excessive use of finalizers, sometimes the objects are queued into a finalization queue. When such an application creates higher priority threads and that leads to more and more objects in the finalizaton queue, it can cause an Out-of-Memory.
*** Exception in thread "main":** java.lang.OutOfMemoryError:PermGen space. If there are many classes and methods loaded or if there are many string literals created, especially through the use of intern() (From JDK 7 on, interned strings are no longer part of the PermGen), then this type of error occurs. When this kind of error occurs, the text ClassLoader.defineClass might appear near the top of the stack trace that is printed. Exception in thread "main": java.lang.OutOfMemoryError: Requested array size exceeds VM limit. This again happens when the requested array size is greater than the available heap size. It may usually occur due to programmatic errors during runtime if an incredibly large value is requested for an array size.
-
Exception in thread "main": java.lang.OutOfMemoryError: request
bytes for . Out of swap space? It is often the root cause of a memory leak. It happens when either the Operating System does not have sufficient swap space or when Another Process hogs all the available memory resources on the system. In simple terms, it was unable to provide the request space from heap due to exhaustion of space. The message indicates the size 's' (in bytes) of the request that failed and the reason 'r' for the memory request. In most cases the part of the message is the name of a source module reporting the allocation failure, although in some cases it indicates a reason. -
Exception in thread "main": java.lang.OutOfMemoryError: (Native method). This indicates that a Native method has met with an allocation failure. The root cause was that the error occurred in JNI rather than in the code executing inside the JVM. When the native code does not check for memory allocation errors, then the application crashes instead of going out of memory.
Definition of Memory Leak
Think of memory leakage as a disease and the OutOfMemoryError as a symptom. But not all OutOfMemoryErrors imply memory leaks, and not all memory leaks manifest themselves as OutOfMemoryErrors.
Some of the most common causes of Memory Leaks are:
- ThreadLocal Variables
- Circular and Complex Bi-Directional References
- JNI Memory Leaks
- Static Fields that are Mutable (Most Common)
Common Debugging of Memory Leaks
- NetBeans Profiler
- 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
Refrences