GARBAGE COLLECTION
Java’s garbage collector is a an automatic memory management
in java.
The heap is the part of memory where Java objects live, and
it’s the one and only part of memory that is in any way involved in garbage
collection process.
When the garbage collector runs, its purpose is to find and
delete objects that can’t be reached.
When does the GC run?
The GC is under the control of JVM ;JVM decides when to run
the GC. From within your Java program you can ask the JVM to run the GC, but
there are no guarantees, under any circumstances, that the JVM will comply.
Left to tits own devices, JVM will typically run the GC when it sense that
memory is running low.
How Does the GC work?
You just can’t be user. You might hear that the GC uses a
mark and sweep algorithm, and for any given java implementation that might be
true, but the Java specification doesn't guarantee any particular
implementation. You might hear that the GC uses reference counting; once again
may be yes, may be no.
When does an object
eligible for GC?
Every Java program has from one to many threads . Each
thread has its own little execution stack. Normally you cause at lease one thread
to run in a java program, the one with the main() method at the bottom of the
stack. In addition to having its own little execution stack, each thread has
its own life cycle. Threads can be alive or dead.
An object is eligible for garbage collector when no live
thread can access it.
If our 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 consider reachable.
Can a Java
application run out of Memory?
Yes, if you maintain
too many live objects the system can run out of memory even though the GC
attempts to remove objects from memory when they are not used.
In old Languages like c++ programmer is responsible for both
creation and destruction of useless objects. Usually programmer taking very
much care while creating objects and neglecting while destroying objects.
Due to this negligence at certain point of time for creation
of new object sufficient memory may not be available and entire application
may down due to memory problems . hence OUTOFMEMORYERROR is very common problem
in old languages.
But in java programmer is responsible just for creation of
objects and he is not responsible destruction of objects. Sun people provided
one assistant which is always running in the background for destruction of
useless objects. Because of this assistant the chance of failing Java program
is very less due to memory problem . this assistant is nothing but “Garbage
Collector”.
Hence the main objective of Garbage collector is to destroy
useless object.
The ways to make an object eligible for GC:
Even though programmer is not responsible to destroy useless
objects but its highly recommended to make an object eligible for GC if it is no
longer required.
An object is said to be eligible for GC if and only if it
doesn't contain any reference.
The following are various ways to make an object eligible
for GC
1. 1. Nullifying the reference variable:
If an object is no longer rewired then
assign null to all its reference variables the object is said to be eligible
for GC
Ex:
Student s1=new Student();
Student s2=new Student();
No objects are eligible for GC
…
S1=null;
One object is Eleigivle for GC
..
S2=null;
Tow objects are eligible for GC
2.
Reassigning the Reference Variable:
If an object is no longer required then
reassigning reference variable to some
other object then the old object is eligible for GC
Ex:
Student s1=new Student();
Student s2=new Student();
No objects are eligible for GC
..
S1=new Student();
…
S2=s1;
Two objects are eligible for GC.
3. 3. Objects created inside a Method:
the objects which are created inside a method are by default eligible for GC once method compelse.
the objects which are created inside a method are by default eligible for GC once method compelse.
P s v main(-)
{
M1();àTwo
objects are eligible for GC
}
P s v M1(){
Student s1=new Student();
Student s2=new Student();
}
}
Ex: class Test{
P s v main(String args[]){
Student s=m1();àonly one object eligible for
GC
}
P s Student m1()
{
Student s1=new Student();
Student s2=new Student();
Return s1;
}
}
If the code is like the below
Class Test{
P s v main(-)
{
M1();àhere
two objects are eligible for GC
}
P s Student m1()
{
Student s1=new Student();
Student s2=new Student();
Return s1;
}
}
4. 4. Island of Isolation:
There is another way in which objects are
become eligible for GC even if they still have valid references! We call this
scenario as “island of isolation”.
A simple example is a class that has an
instance variable that is a reference variable to another instance of the same
class. Now imagine that two such instances exist and that they refer to each
other. If all other references to these two object are remove, then even though
each object still has a valid reference, there will be no way for any live
thread to access either objects. When the GC runs, it can usually discover any
such islands of object and remove them.
Ex:
Class Test
{
Test I;
P s v main(-){
Test t1=new Test();
Test t2=new Test();
Test t3=new Test();
T1.i=t2;
T2.i=t3;
T3.i=t1;
T1=null;
T2=null;
T3=null;àthree objects are eligible for
GC but here no object is eligible for GC
}
}
Even though objects having
references sometimes it is eligible for GC(all references are internal references ex: Island of Isolation)
The methods requesting JVM to run
GC:
Once we made an object eligible
for GC it may or may not be destroyed immediately by the GC.
Whenever JVM runs the GC then only
that object will be destroyed.
Instead of waiting until JVM runs
the GC we can request JVM to run the GC but whether our request is accepted or
not there is no guarantee most of the times JVM accept our request.
The following are possible ways
for requesting JVM to run GC
1. 1. By using system class:
System class contains a static method GC
for this system.gc();
2. 2. By using Runtime class
Java application can communicate with JVM
by using Runtime object.
Runtime object present in java.lang package
and it is a singleton class
We can create Runtime object using
getRuntime()
Ex: Runtime r=Runtime.getRuntime();
Once we got Runtime object we can call the
following method on that object
i.
totolMemory() : returns the no. of bytes of
total memory present in the heap(heap size)
ii.
freeMemory(): returns no of bytes of free memory
present in the heap.
iii.
gc(): for request JVM to run Garbage collector.
Ex:
Import java.util.Date;
Class TimeDemo
{
P s v main(-){
Runtime r=Runtime.getRuntime();
Sop(r.totalMemory());
Sop(r.freeMemory());
For(int i=0;i<10000;i++)
{
Date d=new Date();
D=null;
}
Sop(r.freeMemory());
r.gc();
sop(r.freeMemory());
}
}
Note: Gc method present in system
class is static method where as GC method present in Runtime class is instance
method
->Runtime class is a singleton
class and hence we can’t create object by suing constructor. We have to create
by using factory method.
//valid and invalid
System.gc();//valid
Runtime.gc();//invalid
New Runtime().gc();//invalid
Runtime.getRuntime();//valid
Note: for any java class if we are
allowed to create only one object such type of class is called Singleton class.
Ex: Runtime , Action Servlet
We can create objects for singleton
classes by using FactoryMethod but not by using Constructor.
FactoryMethod:
By using class name if we are
calling a method and if that method returns the same class object such type of
method is called Factory method
Runtime y=Runtime.getRuntime();
Pattern p=Pattern.compile(‘ab”);
Finalization:
Just before destroying an object GC
calls finalize() to perform cleanup activity
Finalize() present in object class
with the following declarations.
Protected void finalize() throws
Throwable
{
{
P s v main(-){
String s=new String(“son”);
S=null;
System.gc();
Sop(“end of main”);
}
Public void finalize(){
Sop(“finalize method called”);
}
}
o/p: end of main
Just before destroying an object
garbage collector always calls finalize on that object then the corresponding
class finalize() will be executed
For example if String object
eligible for GC then String class finalize() will be executed.
In the above example String class
finalize() got executed which has empty implementation
Case i: If we replace String object
with Test object then Test class finalize() will be executed. In this case the
o/p is
Finalize method called
End of main
Or
End of main
Finalize method called
Case ii:
We can call finalize() explicity
then it will be executed like a normal method call and object won’t be
destroyed but before destruction of an object gc always call finalize
Ex:
Class Test{
P s v main(-){
Test t=new Test();
String(“son”);
t.finalize();
t=null;
System.gc();
Sop(“edn of main”);
}
Public void finalize(){
Sop(“Finalize called”);
}
}
o/p:
finalize called
finalize called
end of main
finalize called
In the above example finalize()
will be executed three times and in that 2 times explicity by the programmer
and one time by the garbage collector
Note: we can call destroy() form
the init() and service() explicitly then it will be executed just like a normal
method call and servlet object won’t be destroyed.
But before destroying servlet
object we container always calls destroy
Case iii.
If we are calling finalize()
explicity and while executing finalize() if an exception raised and uncaught
then the program will be terminated abnormally
If garbage collector calls
finalize() and while executing that finalize() if any exception raised and
uncaught then JVM ignores that exception. And rest of the program will be
continued normally.
Ex:
Calss Test
{
P s v main(-){
Test t=new Test();
//t.finalize();---1
T=null;
System.gc();
Sop(“end of main”);
}
Public void finalize(){
Sop(“finalize method called”);
Sop(10/0);
}
}
If we are not commenting line 1
then programmer calling finalize() explicitly and while executing that
finalize() an exception raised which is uncaught hence the program will be
terminated abnormally.
If we are commenting line1 then garbage collector calls finalize() and
while executing that finalize() an exception raised which is uncaught JVM
ignores that exception and rest of the program will be continued normally. In
this case the
o/p:
end of main
finalize method called
which of the following is true?
1.
JVM ignores all exceptions which are raised
while executing finalize()
2.
JVM ignores only uncaught exceptions which are
raised while executing finalize()
Case iv. On any object GC calls finalize only once. Even though object
eligible for GC multiple times
Ex: class finalizeDemo
{
Static finalizeDemo s;
Public s v main(-)throws Exception
{
FinalizeDemo f=new FinalizeDemo():
Sop(f.hashCode());
F=null;
System.gc();
Thread.sleep(5000);
Sop(s.hashCode());
S=null;
System.gc();
Thread.sleep(5000);
Sop(“end of Main method”);
}
Public void finalize(){
Sop(“finalize method called”);
S=this;
}
o/p:
4023232
Finalize method called
4023232
End of main method
In the above program Finalize Demo object is eligible for GC two times.
But GC called finalize() method only once
Case v. we can’t expect exact behaviour of GC. It is JVM Vendor dependent.
Hence we can’t tell exact answers for the following
i.
When exactly JVM runs GC
ii.
What is the algorithm followed by GC
iii.
Whether GC destroys all eligible objects or not.
iv.
In which order GC identifies eligible objects
v.
In which order GC destroys objects etc.
Note : usually whenever the
program runs with low memory then JVM runs GC.
Most of the JVM’s follow Mark and
Sweep algorithm
Case vi.
Memory leak: in our program if any
useless object which is not eligible for GC then such type of objects are
called memory leaks.
In our program if any memory leaks
present then the program will be terminated abnormally by rising Out of Memory
Error
To overcome these memory leaks
when ever an object is no longer required it is highly recommended to make that
object eligible for GC.
The following are various monitoring
tools to identify memory leaks
i.
HP OVO
ii.
IBM TIVOLI
iii.
JPROBE
iv.
HP PATROL
Forcing GC:
In reality, it is possible only to
suggest to JVM that it perform GC. The GC routines that Java provides are
members of the Runtime class. The Runtime class is a special class that has a
single object (a singleton) for each main program. The Runtime object provides
a mechanism for communicating directly with the virtual machine. To get the
Runtime instance, you can use the method Runtime.getRuntime() , which returns
the Singleton. Once you have the singleton, you can invoke the GC using gc()
method.alternatively you can call the same method on the System class, which
has static method that can do the work of obtaining the Singleton for you.
System.gc()
Theoritically after calling
sytem.gc() you will have as much free memory as possible. First your JVM may
not have implemented this routine;the language specification allow this routine
to do nothing at all. Second, another thread might grab lots of memory right
after you run the GC .
Ex:
Import java.util.Date;
Public class CheckGC{
Public static void main(-){
Runtime rt=Runtime.getRuntime();
Sop(“Total JVM
meory”+rt.totalMemory());
Sop(“Before
Memory”+rt.freeMemory());
Date d=new Date();
For(int i=0;i<1000;i++){
D=new Date();
D=null;
}
Sop(“After
memory”+rt.freeMemory());
Rt.gc();//an alternate to
System.gc();
Sop(“After GC
Memory”+rt.freeMemory());
}
}
o/p:
Total JVM meory 1048568
Before Memory 703008
After Memory 458058
After GC Memory 818272
Note : the behavior when gc() is
called may be different for different JVMs, so there is no guarantee that the
unused objects will be removed from memory. The only thing we can guarantee
that if you are running very low on memory, the GC will run before it throws an
OutOfMemoryException.
Finalize(): Cleaning up Before GC
As you may have gathered by now,
you can never count on the GC to delete the object. So any code that you put
into your class’s overridden finalize() method is not guaranteed to run.
Because the finalize() method for any give object might run, but you can’t
count on it, don’t put any essential code into your finalize() method. In fact
, we recommend that in general you don’t override finalize() at all.
For any object, finalize() will be
called only once by the GC
Calling finalize() can actually
result in saving an object from deletion.
KEY POINTS:
·
In java, GC provides automated memory management
·
The purpose of GC is to delete objects that
can’t be reached
·
Only the JVM decides when to run the GC; you can
only suggest it
·
You can’t know the GC algorithm for sure
·
Objects must be considered eligible before they
can be Garbage collected
·
An object is eligible when no live thread can
reach it
·
To reach an object , you must have alive,
reachable reference to that object
·
Java applications can run out of memory
·
Island of objects can be gc, even though they
refer to each other
·
Request GC with system.gc()
·
The class object has a finalize() method
·
The finalize() method is guaranteed to run once
and only once before the gc deletes the object
·
The gc makes no guaranteed; finalize() may never
run
·
You can ineligible-ize an object for GC from within
finalize()
Comments
Post a Comment