Garbage Collection
Garbage Collection
Collection
Dr Richa,
Assistant Professor
Introduction
• Garbage collection in Java is the process by which Java programs
perform automatic memory management.
• Java programs compile to bytecode that can be run on a Java Virtual
Machine, or JVM for short.
• When Java programs run on the JVM, objects are created on the heap,
which is a portion of memory dedicated to the program.
• Eventually, some objects will no longer be needed. The garbage
collector finds these unused objects and deletes them to free up
memory.
Introduction
• Unlike C++, programmer need not care for all those objects which are
no longer in use. Garbage collector destroys these objects.
• The main objective of Garbage Collector is to free heap memory by
destroying unreachable objects.
Working of GC
• Automatic garbage collection is the process of looking at heap
memory, identifying which objects are in use and which are not, and
deleting the unused objects.
• The garbage collection implementation lives in the JVM.
Memory Heap Generation
• Eden: The eden space in Java is a memory pool where objects are created.
When the eden space is full, the garbage collector either removes objects if
they are no longer in use or stores them in the survivor space if they are still
being used. This space is considered part of the young generation in the
memory heap.
• Survivor: There are two survivor spaces in the JVM: survivor zero and
survivor one. This space is also part of the young generation.
• Tenured: The tenured space is where long-lived objects are stored. Objects
are eventually moved to this space if they survive a certain number of garbage
collection cycles. This space is much larger than the eden space and the
garbage collector checks it less often. This space is considered the old
generation in the heap.
Working of Garbage Collector
• Garbage collection occurs most frequently in the eden space because
many new objects don’t need to stay in memory for very long. However,
it wouldn’t make sense for the garbage collector to keep checking
uncollected objects over and over, particularly if an object needs to
remain in the heap for a long time. That’s an inefficient use of the
collector. By moving objects into survivor and tenured spaces, the
garbage collector knows that there is a higher likelihood that the objects
there will need to remain in memory, so it checks those areas less
frequently. Because the tenured space is much larger than the eden space,
it fills up less regularly and the garbage collector doesn’t check it as
much. The potential downside is that the tenured space is more prone to
memory leaks since it isn’t checked as regularly.
Types of activity in Java GC
1.Minor or incremental Garbage Collection: It is said to have
occurred when unreachable objects in the young generation heap
memory are removed.
2.Major or Full Garbage Collection: It is said to have occurred when
the objects that survived the minor garbage collection are copied into
the old generation or permanent generation heap memory are
removed. When compared to the young generation, garbage collection
happens less frequently in the old generation.
Unreachable objects: An object is said to be unreachable if it doesn’t contain any
reference to it. Also, note that objects which are part of the island of isolation are also
unreachable.
• Once we make an object eligible for garbage collection, it may not destroy
immediately by the garbage collector. Whenever JVM runs the Garbage
Collector program, then only the object will be destroyed. But when JVM runs
Garbage Collector, we can not expect.
• We can also request JVM to run Garbage Collector. There are two ways to do
it :
• Using System.gc() method: System class contain static method gc() for requesting JVM
to run Garbage Collector.
• Using Runtime.getRuntime().gc() method: Runtime class allows the application to
interface with the JVM in which the application is running. Hence by using its gc()
method, we can request JVM to run Garbage Collector.
• There is no guarantee that any of the above two methods will run Garbage Collector.
• The call System.gc() is effectively equivalent to the call : Runtime.getRuntime().gc()
Finalization
•Just before destroying an object, Garbage Collector calls finalize() method on the
object to perform cleanup activities. Once finalize() method completes, Garbage
Collector destroys that object.
•finalize() method is present in Object class with the following prototype.
protected void finalize() throws Throwable
Based on our requirement, we can override finalize() method for performing our
cleanup activities like closing connection from the database.
1.The finalize() method is called by Garbage Collector, not JVM. However, Garbage Collector
is one of the modules of JVM.
2.Object class finalize() method has an empty implementation. Thus, it is recommended to
override the finalize() method to dispose of system resources or perform other cleanups.
3.The finalize() method is never invoked more than once for any object.
4.If an uncaught exception is thrown by the finalize() method, the exception is ignored, and
the finalization of that object terminates.
Real World Example
• Suppose you are in a company, and you were told to write a program to count the
number of employees working in the company(excluding interns). To make this
program, you have to use the concept of a garbage collector.
• Write a program to create a class called Employee having the following data
members.
• An ID for storing unique id allocated to every employee.
• Name of employee.
• Age of an employee.
• Also, provide the following methods:
1.A parameterized constructor to initialize name and age. The ID should be initialized in this
constructor.
2.A method show() to display ID, name, and age.
3.A method showNextId() to display the ID of the next employee.
General Method
class Employee{
private int ID;
private String name;
private int age;
private static int nextId = 1;
// it is made static because it keep common among all and shared by all objects
public Employee(String name, int age) {
this.name = name;
this.age = age;
this.ID = nextId++;
}
public void show() {
System.out.println("Id=" + ID + "\nName=" + name + "\nAge=" + age);
}
public void showNextId() { // It is sub block to keep all those interns.
System.out.println("Next employee id will be=" + nextId); Employee X = new Employee("GFG4", 23);
} Employee Y = new Employee("GFG5", 21);
} X.show();
Y.show();
public class Main{
X.showNextId();
public static void main(String[] args) {
Y.showNextId();
Employee E = new Employee("GFG1", 56); }
Employee F = new Employee("GFG2", 45); // After countering this brace, X and Y will be removed.
Employee G = new Employee("GFG3", 25); Therefore, now it should show nextId as 4.
E.show(); // Output of this line
F.show(); E.showNextId();
// should be 4 but it will give 6 as output.
G.show();
}
E.showNextId();
}
F.showNextId();
G.showNextId();
{
With less data
class Employee{
private int ID; private String name; private int age;
private static int nextId = 1;
// it is made static because it keep common among all and shared by all objects
public Employee(String name, int age) {
this.name = name; this.age = age; this.ID = nextId++;
}
public void show() {
System.out.println("Id=" + ID + "\nName=" + name + "\nAge=" + age);
}
public void showNextId() {
System.out.println("Next employee id will be=" + nextId);
}
}
public class Main{
public static void main(String[] args) {
Employee E = new Employee(“ABC", 56);
E.show();
E.showNextId();
{
// It is sub block to keep all those interns.
Employee X = new Employee(“XYZ", 23); X.show();
X.showNextId();
}
// After countering this brace, X and Y will be removed. Therefore, now it should show nextId as 4.
Output of this line
E.showNextId(); // should be 4 but it will give 6 as output.
}
}
Using gc()
class Employee{
private int ID; private String name; private int age;
private static int nextId = 1;
// it is made static because it keep common among all and shared by all objects
public Employee(String name, int age) {
this.name = name; this.age = age; this.ID = nextId++;
}
public void show() {
System.out.println("Id=" + ID + "\nName=" + name + "\nAge=" + age);
}
public void showNextId() {
System.out.println("Next employee id will be=" + nextId);
}
}
public class Main{
public static void main(String[] args) {
Employee E = new Employee(“ABC", 56);
E.show();
E.showNextId();
{
// It is sub block to keep all those interns.
Employee X = new Employee(“XYZ", 23); X.show();
X.showNextId();
X=null; System.gc(); System.runFinalization();
}
// After countering this brace, X and Y will be removed. Therefore, now it should show nextId as 4. Output
of this line
E.showNextId(); // should be 4 but it will give 6 as output.
}
}
Using GC
class Employee{
private int ID;
private String name;
private int age;
private static int nextId = 1;
// it is made static because it keep common among all and shared by all objects
public Employee(String name, int age) {
this.name = name;
this.age = age;
this.ID = nextId++;
}
public void show() {
System.out.println("Id=" + ID + "\nName=" + name + "\nAge=" + age);
}
E.showNextId();
F.showNextId();
G.showNextId();
{
public void showNextId() { // It is sub block to keep all those interns.
System.out.println("Next employee id will be=" + nextId); Employee X = new Employee("GFG4", 23);
} Employee Y = new Employee("GFG5", 21);
protected void finalize() X.show();
Y.show();
{
X.showNextId();
--nextId;
Y.showNextId();
// In this case, gc will call finalize() for 2 times for 2 objects. X=null;Y=null;
} System.gc();
} System.runFinalization();
public class Main{ }
public static void main(String[] args) { // After countering this brace, X and Y will be removed.
Employee E = new Employee("GFG1", 56); Therefore, now it should show nextId as 4.
// Output of this line
Employee F = new Employee("GFG2", 45);
E.showNextId();
Employee G = new Employee("GFG3", 25);
// should be 4 but it will give 6 as output.
E.show(); }
F.show(); }
G.show();
Ways to make an object eligible for Garbage
Collector
• Create an object inside a method. After methods are executed, all objects called
within those methods become unreachable, which makes them eligible for garbage
collection.
• Nullify the reference variable. You can change a reference variable to NULL. As
long as all references to an object are removed, that object will become unreachable,
which lets the garbage collector know the object can be removed.
• Reassign the reference variable. Instead of nullifying the reference variable, you
can also reassign the reference to another object. Once again, as long as all references
to an object are removed, either through making reference variables NULL or
reassigning them, the object will become inaccessible, leading to it being removed
during the garbage collection process.
• Create an anonymous object. An anonymous object doesn’t have a reference, so the
garbage collector will mark and remove it during the next garbage collection cycle.
Object inside a method
• When a method is called it goes inside the stack frame. When the
method is popped from the stack, all its members dies and if some
objects were created inside it then these objects becomes unreachable
or anonymous after method execution and thus becomes eligible for
garbage collection
Example
public class Main{
String obj_name; public static void main(String[] args) {
show();
public Main(String obj_name) {
System.gc();
this.obj_name=obj_name; }
} protected void finalize() throws Throwable
public static void show() { {
System.out.println(this.obj_name+ "
Main m1=new Main("T1");
collected by GC successfully");
display(); }
} }
public static void display() {
Main m2=new Main("T2");
}
Reassigning the reference variable