0% found this document useful (0 votes)
40 views54 pages

Garbage Collection

Uploaded by

Bhavish Jain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views54 pages

Garbage Collection

Uploaded by

Bhavish Jain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 54

Garbage

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.

Integer i = new Integer(4);


// the new Integer object is reachable via the reference in 'i’
i = null;
// the Integer object is no longer reachable.

Eligibility for garbage collection: An object is said to be eligible for GC(garbage


collection) if it is unreachable. After i = null, integer object 4 in the heap area is
suitable for garbage collection in the above image.
Important Point
• You can’t force garbage collection on a specific object, but you can
update objects so they are no longer accessible to the rest of the
application. This lets the garbage collector know that those objects
should be removed.
Ways to make an object eligible for Garbage
Collector
• Even though the programmer is not responsible for destroying useless
objects, but it is highly recommended to make an object
unreachable(thus eligible for GC) if it is no longer required.
• There are generally four ways to make an object eligible for garbage
collection.
• Nullifying the reference variable
• Re-assigning the reference variable
• An object created inside the method
• Island of Isolation
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.
How objects are unreferenced
• By nulling the reference
• Employee e=new Employee();
• e=null;
• By assigning a reference to another
• Employee e1=new Employee();
• Employee e2=new Employee();
• e1=e2;//now the first object referred by e1 is available for garbage collection
• By anonymous object etc.
• new Employee();
Example
public class Main{
public void finalize(){
System.out.println("Object collected");
}
public static void main(String[] args)
{
Main m=new Main();
Main m1=new Main();
m=null;
m1=null;
System.gc();
//Runtime.getRuntime().gc();
}
}
Output: object collected
Object collected
• The finalize() method is invoked each time before the object is garbage collected. This
method can be used to perform cleanup processing. This method is defined in Object
class as:
• protected void finalize(){}
• Note: The Garbage collector of JVM collects only those objects that are created
by new keyword. So if you have created any object without new, you can use
finalize method to perform cleanup processing (destroying remaining objects).
• The gc() method is used to invoke the garbage collector to perform cleanup processing.
The gc() is found in System and Runtime classes.
• public static void gc(){}
• Garbage collection is performed by a daemon thread called Garbage
Collector(GC). This thread calls the finalize() method before object is garbage
collected.
Ways for requesting JVM to run Garbage Collector

• 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

• When reference id of one object is referenced to reference id of some


other object then the previous object has no any longer reference to it
and becomes unreachable and thus becomes eligible for garbage
collection
Nullify the reference

• 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.
Nullify the reference Example
public class Main{
public static void main(String[] args) {
Main m=new Main();
m=null;
System.gc();
}
protected void finalize() throws Throwable {
System.out.println(" successfully garbage collected");
}
}
Output: successfully garbage collected
To prevent object of a class from Garbage
Collection in Java
• By Increasing Heap Memory
• In netbeans inside config vm options: -Xms256m: Xmx specifies
the maximum memory allocation pool for a Java virtual machine
(JVM), while Xms specifies the initial memory allocation pool.
• This approach leads to the garbage collector running infrequently,
however when it runs, will take longer than before to complete the
garbage collection task.
To prevent object of a class from Garbage
Collection in Java
• In case of a singleton class, the reference of the only object created can
be stored in a static reference.
• Since static members are stored in class area (a memory segment),
their lifetime spans the lifetime of the program.
Finalize Method()
• finalize() method in Java is a method of the Object class that is used to
perform cleanup activity before destroying any object. It is called
by Garbage collector before destroying the objects from
memory. finalize() method is called by default for every object before
its deletion.
Finalize() Method
• finalize() is a method of the Object class in Java. The finalize() method is a non-
static and protected method of java.lang.Object class. In Java, the Object class
is superclass of all Java classes. Being an object class method finalize() method
is available for every class in Java. Hence, Garbage Collector can call finalize()
method on any Java object for clean-up activity.
• finalize() method in Java is used to release all the resources used by the object
before it is deleted/destroyed by the Garbage collector. finalize is not a reserved
keyword, it's a method. Once the clean-up activity is done by
the finalize() method, garbage collector immediately destroys the Java
object. Java Virtual Machine(JVM) permits invoking of finalize() method only
once per object. Once object is finalized JVM sets a flag in the object header to
say that it has been finalized, and won't finalize it again. If user tries to
use finalize() method for the same object twice, JVM ignores it.
Garbage Collector in Java
• Anonymous object : new Student();
• Nulling reference: Test t=new Test(); t=null;
• By assigning a reference to another object:
Test t1=new Test();
Test t2=new Test();
t1=t2;
Contd..
The garbage collector is a part of Java Virtual Machine(JVM). Garbage
collector checks the heap memory, where all the objects are stored by JVM, looking
for unreferenced objects that are no more needed. And automatically destroys those
objects. Garbage collector calls finalize() method for clean up activity before
destroying the object. Java does garbage collection automatically; there is no need
to do it explicitly, unlike other programming languages.
The garbage collector in Java can be called explicitly using the following method:
System.gc();
System.gc() is a method in Java that invokes garbage collector which will destroy
the unreferenced objects. System.gc() calls finalize() method only once for each
object.
Finalize() method with Garbage Collection
• JVM calls the garbage collector to delete unreferenced objects. After
determining the objects that have no links or references, it calls
the finalize() method which will perform the clean activity and the
garbage collector destroys the object.
Clean up activity
• Cleanup activity is the process of closing all the resources being used
by an object before it is destroyed. Resources that can be used by any
object are database connections, network connections, etc. These
resources are released and clean-up activity is performed by the
garbage collector in Java and then the object is deleted.
• The major advantage of performing clean-up before garbage collection
is data resources or network connections that are linked
to unreferenced object are revoked and can be used again. Cleanup
ensures resources are not linked to objects unnecessarily and helps
JVM in boosting memory optimization and speed.
Finalize() Method in Java
• Garbage collection is done automatically in Java which is handled by JVM, and it uses finalize
method in Java for releasing the resources of the object, that has to be destroyed.
• finalize() method gets called only once by GC, if an exception is thrown by finalizing method or the
object revives itself from finalize(), the garbage collector will not call the finalize() method again.
• It's not guaranteed if the finalized method will be called or not, or when it will be called. Relying
completely on finalization to release resources is not recommended.
• There are other ways to release the used resources in Java like the close() method in case of file
handling or destroy() method. But the issue with these methods is they don't work automatically, we
must call them manually every time.
• In such cases, to improve the chances of performing clean-up activity, we can use finalize() method
in final block. finally block will execute finalize() method even though the user has
used close() method manually.
• We can use finalize() method to release all the resources used by the object, in finally block by
overriding finalize() method.
To override finalize() method
• We know that finalize() is a protected method of Object class of Java.
finalize() method in Java has an empty implementation. Hence, we can
use it in our class by overriding it. finalize() method can be overridden
in our class reason being Object class is the parent class of all the
classes in Java. If our class, has clean-up activities then we have to
override this method explicitly to perform our clean-up activities.
Example
public class Main{
public static void main(String[] args) {
Main m=new Main();
m=null;
System.gc();
}
protected void finalize() throws Throwable {
System.out.println(" successfully garbage collected");
}
}
Output: successfully garbage collected.
m is an object of example class is unreferenced and destroyed by the garbage collector. This garbage
collector called overridden finalize method before destroying the object.
Various scenarios of finalize() method in
different cases
• Finalize() method of which class is being called:
Example
public class Main{
public static void main(String[] args) {
String m=new String();
m=null;
System.gc();
System.out.println(" After garbage collected");
}
protected void finalize() throws Throwable {
System.out.println(" successfully garbage collected");
}
}
Output: After garbage collected
Garbage Collector calls the finalize method of that class whose object is eligible for Garbage
collection. In the above program m = null; m is the object of String class not of Main class. So,
when System.gc(); invokes garbage collector it calls the finalize() method of String class in java and the
Another Example using GC
public class Main{
public static void main(String[] args) {
Main m=new Main();
m=null;
System.gc();
}
protected void finalize() throws Throwable {
System.out.println(" successfully garbage collected");
}
}
Output: successfully garbage collected.
m is an object of example class is unreferenced and destroyed by the garbage collector. This garbage
collector called overridden finalize method before destroying the object.
Explicit call to finalize() method
• When we call finalize() method explicitly, the JVM treats it as a
normal method, it is not able to remove the object from
memory. finalize() method can release memory and resources related
to an object only when it's called by a Garbage collector. Compiler
will ignore finalize() method if it's called explicitly and not invoked by
the Garbage collector.
Garbage Collector in Java
• four different options for garbage collectors, each with its own pros and cons.
• Serial Garbage Collector: The serial garbage collector is typically used for
smaller, single-threaded environments. Don’t use it in a production
environment because the process of garbage collection takes over the thread,
freezing other processes. This is known as a “stop the world” event.
• Parallel Garbage Collector: The parallel garbage collector is JVM’s default
garbage collector. As the name implies this garbage collector uses multiple
(parallel) threads. Because it can also use multiple CPUs to speed up
throughput, it’s also known as the throughput collector. However, when
running garbage collection, it will also freeze application threads.
• Concurrent Mark and Sweep (CMS) collector: Like the parallel
garbage collector, the concurrent mark-and-sweep collector uses
multiple threads. However, this collector is known as a “low-pause”
collector because it freezes application threads less frequently, making
it more appropriate for user-facing applications where “stop the
world” events will cause issues for your users. It can only garbage
collect the old generation concurrently, though—it still needs to freeze
execution when collecting the young generation. Also, because the
collector’s threads execute at the same time as the application’s
threads, it does use more processing power than other garbage
collectors.
• Garbage First (G1) Garbage Collector: The G1 garbage collector takes
a different approach altogether. Instead of collecting the young and old
generations separately, it can collect both at once by splitting the heap
into many spaces—not just the eden, survivor, and tenured spaces that
other garbage collectors use. This allows it to clear smaller regions
instead of clearing large regions all at once, optimizing the collection
process. It runs concurrently like the CMS collector, but it very rarely
freezes execution and can collect both the young and old generations
concurrently.
Mark and Sweep
• The Java garbage collection process uses a mark-and-sweep algorithm.
Here’s how that works:
• There are two phases in this algorithm: mark followed by sweep.
• When a Java object is created in the heap, it has a mark bit that is set to 0
(false).
• During the mark phase, the garbage collector traverses object trees starting at
their roots. When an object is reachable from the root, the mark bit is set to 1
(true). Meanwhile, the mark bits for unreachable objects is unchanged.
• During the sweep phase, the garbage collector traverses the heap, reclaiming
memory from all items with a mark bit of 0 (false).
Mark and Sweep Algorithm
• Any garbage collection algorithm must perform 2 basic operations. One, it should be able
to detect all the unreachable objects and secondly, it must reclaim the heap space used by
the garbage objects and make the space available again to the program. The above
operations are performed by Mark and Sweep Algorithm in two phases as listed and
described further as follows:
• Mark phase
• Sweep phase
• Phase 1: Mark Phase
• When an object is created, its mark bit is set to 0(false). In the Mark phase, we set the
marked bit for all the reachable objects (or the objects which a user can refer to) to 1(true).
Now to perform this operation we simply need to do a graph traversal, a
depth-first search approach would work for us. Here we can consider every object as a node
and then all the nodes (objects) that are reachable from this node (object) are visited and it
goes on till we have visited all the reachable nodes.
• Phase 2: Sweep Phase
• As the name suggests it “sweeps” the unreachable objects i.e. it clears
the heap memory for all the unreachable objects. All those objects
whose marked value is set to false are cleared from the heap memory,
for all other objects (reachable objects) the marked bit is set to true.
Now the mark value for all the reachable objects is set to false since
we will run the algorithm (if required) and again we will go through
the mark phase to mark all the reachable objects.

You might also like