Automatic Garbage Collection in Java

One of the stand out features of the Java programming language is the automatic reclamation of memory space, a technique known as the garbage collection. In languages like C++ the developers are forced to manually allocate and de-allocate memory to objects. This gives the developer an extra burden to work with and also allowing the possibility for memory leaks. Memory leakage occurs when the developer doesn’t de-allocate the memory for objects after their usage, which leads to the gradual depletion of memory. Automatic reclamation of the memory in Java frees the developer from having to keep track of when to free the allocated memory.

Garbage Collector(GC) being an important feature of Java prevents programmers from accidentally (or purposely) crashing the JVM by incorrectly freeing memory. A potential disadvantage of a GC is that it adds an overhead that can affect program performance. The JVM has to keep track of which objects are being referenced by the executing program, and finalize and free unreferenced objects on the fly. This activity will likely require more CPU time than would have been required if the program explicitly freed unnecessary memory. In addition, programmers in a garbage-collected environment have less control over the scheduling of CPU time devoted to freeing objects that are no longer needed.
An object is eligible for garbage collection when no live thread can reach it. When we talk about reaching an object,we’re really talking about having a reachable reference variable that refers to the object in question. So if a Java program has a reference variable that refers to an object, and that reference variable is available to a live thread, then that object is considered reachable.
Even though Java has the feature of automatic garbage collection it can still run out of memory. Basically the GC attempts to remove objects when they are not used. So if the program maintains a lot of live objects, the system can run out of memory since GC cannot ensure that there is enough memory.
The GC is in the control of the JVM and the JVM decides when to run the GC. The programmer can request the JVM to run the GC but under no guarantees, under any circumstances, that the JVM will comply. But experience indicates that when the programmer puts a request for garbage collection, the JVM usually grants the request in short order, but with no guarantees. There are two ways to request for a garbage collection in a program. Calling the gc() method on the singleton object of the Runtime class. We can get the Runtime instance by calling the Runtime.getRuntime() method. The second way is to call the same gc() method on the System class (System.gc()).
Java provides a mechanism to run some code just before your object is deleted by the GC. This code can be put into the finalize() method that every object inherits from the Object class. For any object the finalize() method will be called only once(at most) by the GC. Since we are not sure when the GC runs and so we cannot count on the finalize() method to run. So putting in sensitive or important code in the finalize() method might result in a disaster and it is sometimes recommended not to override the finalize() method.