Garbage collection is the process to manage memory, First GC
identify whether the objects are in use or not. An unused object, or
unreferenced object, is no longer referenced by any part of the program. So the
memory used by an unreferenced object can be reuse.
In a programming language like C, allocating and deallocating memory is a manual process. In Java, process of deallocating memory is handled automatically by the garbage collector. The basic process can be described as follows.
In a programming language like C, allocating and deallocating memory is a manual process. In Java, process of deallocating memory is handled automatically by the garbage collector. The basic process can be described as follows.
1. The first step is called marking,
in this step GC identify the unused memory reference.
2. The 2n step is
to removes unreferenced objects and pointers to free space.
To improve the performance GC do deletion and
compacting, here GC delete the unreferenced objects also do the compacting of
remaining referenced objects. By moving the referenced objects together, this
make new memory allocation much easier and faster.
Important
points-
How an object is eligible for GC?
By nulling the reference – check below code snippet
Student
student = new Student();
//here we are nulling
student reference after this line
//after below line
memory location used by student will
//be available for
GC
student = null;
By assigning a reference to other –
Student
studentOne = new Student();
Student
studentTwo = new Student();
//here we are
assigning the reference of studentTwo into studentOne
//after below line
memory location used by studentOne
//will be available
for GC
studentOne = studentTwo;
By anonymous object
//here we are
creating a new object but this
//memory location
is not assign to any reference
//variable so it's
eligible for GC
new Student();
Can we forced the Garbage Collection?
No we can’t force garbage collection but via calling System.gc()
we can request for GC
Code snippet –
System.gc();
//or
Runtime
runtime = Runtime.getRuntime();
runtime.gc();
This does not guarantee that JVM will perform the
garbage collection and Java never recommend to use gc() method because calling
System.gc() method will affect the system performance drastically
What is the use of finalize () method?
If we need to perform some specific task
before an object get destroyed like closing an open connection or releasing any
resources. To handle this situation finalize() method is used. finalize() method is called by garbage collection befor
cleanup.
Code snippet of finalize() is
/**
* Overriding finalize method to release
resource
* before GC is performed
*/
protected void finalize() throws Throwable {
try{
System.out.println("Finalizing");
//release resources;
}catch(Throwable throwable){
throw throwable;
}finally{
System.out.println("Calling
object class finalize() method");
super.finalize();
}
}
finaliz() method call only once by GC threads to make
sure that cyclic redundancy doesn’t happened. We never prefer to use finalize()
method because it’s a heavy performance impact.
Functioning
on GC
As per the life of java object we classified the two generation for GC
Young
Generation – Most of the objects become unreachable soon, these objects are created
in the young generation. A "minor GC" has occurred in young generation
as these object destroyed in a short time.
Old
generation: The objects who survived from the young generation are moved to old
generation. It is larger than the young generation. As it is bigger in size,
the GC occurs less frequently than in the young generation. A "major GC"
(or a "full GC") has occurred in old generation.
Permanent generation is removed in JAVA8 and replaced with Metaspce
Composition
of the Young Generation –
The young generation is divided into 3 spaces.
1.
One Eden space
2.
Two Survivor spaces
The order of execution process of these space is as below:
1.
The majority of newly created objects are located in the Eden space.
2.
The object which are survived in GC of Eden space are moved to one of the
Survivor spaces.
3.
Once a Survivor space is full, surviving objects are moved to another
Survivor space.
4.
The objects that survived these steps that have been repeated a number of
times are moved to the old generation.
Memory allocation techniques-
For faster memory allocation these two techniques are used
Bump-the-pointer
-
In this technique tracks the last object allocated on the top of the Eden
space. If there is an object created afterwards, it checks only if the size of
the object is suitable for the Eden space. If it seems right, it will be placed
in the Eden space, and the new object goes on top. So, when new objects are
created, only the lastly added object needs to be checked, which allows much
faster memory allocations. However, it is a different story if we consider a
multithreaded environment to save objects used by multiple threads in the Eden
space for Thread-Safe, an inevitable lock will occur and the performance will
drop due to the lock-contention.
TLABs
(Thread-Local Allocation Buffers)-
TLABs is the solution for multithreaded environment. This allows each
thread to have a small portion of its Eden space. So here each thread can only
access to their own TLAB.
Type
of GC
According to JDK 7, there are 5 GC types.
1.
Serial GC
2.
Parallel GC
3.
Parallel Old GC (Parallel Compacting GC)
4.
Concurrent Mark & Sweep GC (or
"CMS")
5.
Garbage First (G1) GC
Serial GC
(-XX:+UseSerialGC)-
This GC type was created when there was only one CPU core on desktop
computers. Using this serial GC will drop the application performance
significantly.
The GC in the old generation uses an algorithm called
"mark-sweep-compact."
1.
The first step is to mark the surviving objects in the old generation.
2.
Then checks the heap from the front and leaves only the surviving ones
behind (sweep).
3.
In the last step, it fills up the heap from the front with the objects so
that the objects are piled up consecutively, and divides the heap into two
parts: one with objects and one without objects (compact).
The
serial GC is suitable for a small memory and a small number of CPU cores.
Parallel GC
(-XX:+UseParallelGC)
The parallel GC uses several threads to process a GC, and therefore it is
faster. This GC is useful when there is enough memory and a large number of
cores. It is also called the "throughput GC."
Parallel Old
GC(-XX:+UseParallelOldGC)
It algorithm goes through three steps: mark – summary – compaction.
The summary step identifies the surviving objects and then it perform
mark-sweep-compact algorithm.
CMS GC
(-XX:+UseConcMarkSweepGC)
The Concurrent Mark-Sweep GC more complicated than other GC. The early
initial mark step is simple. It search for surviving objects that are closest
to the classloader. So, the pausing time is very short. In the concurrent mark
step, the objects referenced by the surviving objects are tracked and checked.
The difference of this step is that it proceeds while other threads are
processed at the same time. In the remark step, the objects that were newly
added or stopped being referenced in the concurrent mark step are checked.
Lastly, in the concurrent sweep step, the garbage collection procedure takes
place. In this GC all the step perform in parallel the pausing time is very
short. The CMS GC is also called the low latency GC, and is used when the
response time from all applications is crucial.
G1 GC
This algorithm is completely different from above GC algorithm, in this
algorithm one object is allocated into a grid, and then a GC is executed. Then, once
one area is full, the objects are allocated to another area, and then a GC is
executed.
The biggest advantage of the G1 GC is its performance. It is faster than
any other GC types.
junk removal pittsburg ca Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon. Big thanks for the useful info.
ReplyDelete