Java Garbage Collector is responsible to sweep all the garbage objects remains in memory and leave only those objects which are still referenced on the memory stack. For this, JVM uses 'Mark-Sweep-Compact' three phase techniques. Here JVM give three passes to memory objects to destroy the garbage objects. The process is
- In first pass, GC traverses on the Memory Stack and mark all the objects which are referenced from Memory Stack through any scope data structure.
- In second pass, GC claims the space of all unmarked objects to release their memory. Before claiming the objects for collection, the demon thread, Garbage Collector, call 'finalize' method of the object in order to give it a chance to do the resource cleanup. Here if any object resurrect it again, i.e. do some activity which put its memory reference back to Memory Stack, garbage collector won't collect its memory and leave this. However in this process, GC maintains a state for the objects for which 'finalize' method has already been called once. In next garbage collection cycle, it does not call the 'finalize' method on this object.
- In third pass, garbage collector compact the memory space which was released by second pass and hence made the released memory available for JVM.
This way, GC manages the memory. The process followed to manage the memory is not light in its processing, as three phases process takes a lot of time to execute and hence is a heavy process. Due to this, JVM does not call the GC very often, but it calls it only when it really feels that memory is low and program may need more memory soon. So even if you are calling System.gc(), it does not mean that JVM will call the GC. However it is just like a request to JVM to consider calling the GC. But JVM has its internal logic to decide when to call the GC.
'Finalize' method is used for resource cleaning process by most of the applications. You can use this method to release any resource like ObjectOutputStream, any handle to an OS file etc. But be very careful while relying on this method. Reason is that JVM does not guarantee to call the finalize method. Consider a condition, when program never face a memory pressure and hence JVM never finds the need to call the GC.