Efficient Memory Management
in Java   - Article 1
 In our day to day life , we deal with classes , objects and
functions in the world of java . These  are pretty much the things
which full fills all are daily needs with the help of different
design  patterns and  programming standards. In most of the work we
do performance has been the  criteria for most of our application ,
but normally time takes the precedence over space. Due to  which we
sometimes end up issues related to memory.
 As we know Java is language which takes a huge heap over other
languages like C and C++   with respect to memory management. We are
no longer required to allocate and de-allocate  memories in java .
During the java's life cycle , memory management has evolved a lot
with  more intelligence being inducted in JVM and GC (Garbage
Collector). In the recent version of  JDK (JDK 7) , a completely new
Garbage collector Algo (G1) has been introduced. 
 Now
the big question : THEN WHY DO WE STILL GET
MEMORY EXCEPTION
 There are 2 main reasons
- Bad coding practices : Every java developer does this , in some way or the other.
 - GC is unpredictable : Java provide certain guarantee regarding its GC but it's purely
 
impossible
to predict the GC operation at a given time.
 We won't dig deep here with respect to Point (1) . This could be
eradicated by using proper  coding standards , effective code review
and even by using external tools for Memory  management
 Coming
to Point (2) , As mentioned earlier its impossible to predict the GC
operation at a given  time . The reason being very clear that , GC
internally depends on OS scheduling mechanism  and OS memory
management which is not controlled by Java  . Said this java provides
us with  certain mechanism which can make our life easy regarding
Memory management. And the most  important of them is References
 Short
Description on GC in Java
 Not
digging deep , GC mechanism contains basically 3 steps 
- Checking if object is not reachable , if Yes
 
a)  Check if object implements finalize() method , if so add to
finalization queue
b)  Else , make the object finalized
        2)   If (a) section of Point (1) was true , then pick the
object from finalization queue and run    the finalize method and
make object finalized
                  3)
 Garbage collector picks the object and de–allocates the memory
            **(GC
is a detailed topic and would be picked up in coming up journals)
 Jumping
to References in Java
 References
as going by Wikipedia 'is
a relation between objects in which one object  designates'
and
nothing changes in java.
 Before
Jumping into the references , we need to know about reference Queue
 ReferenceQueue
as java doc says 'to
which registered reference objects are appended by   the garbage
collector '
. So at a point when GC realizes that any of the reference to which
it is  listening is ready for garbage collection. GC inserts that
particular object into Reference Queue . 
 There
are basically 4 time of Reference in java . In this article , we
would be focusing mainly on
 2 type of reference
 a) Strong reference : 
  These are most common and widely used references . 
    public List  obj1=new ArrayList();
  Here
obj1 is a strong reference
and GC can't in any case de-allocate the memory    grabbed by
ArrayList until obj1
doesn't gets unreferenced ( goes out of scope) or at least   it
starts pointing to another object . 
 But these references might not be the best choice . Specially , when
you have heavy data lying  in your memory like a File Object ,a heavy
database result set etc.
 This is the place where other options come into picture
 b) Weak References :
  As
java doc says : 'Weak
reference objects, which do not prevent their referents from    being
made finalizable, finalized, and then reclaimed  '. 
  As
the name suggest ,it sets up a weak reference to an object . For e.g.
  The first parameter (k)  is the object on which weak
reference is being created and the    second one is the Reference
Queue (rq) 
  As we know, its
difficult to understand this concept without digging into the code ,
so    lets pic one simple example .
  We would be needing 2
simple POJO's as helper classes for our example.
     
 Keybean.java
      KeyBeanParent.java
  Now lets come to a simple weak Reference
article
                                           SimpleWeakReference.java
                                                              Output
  Now
lets go point by point 
  Initially
we create 2 strong references for KeyBean and
KeyBeanParent parent.
  (1)
–
As you could see KeyBeanParent
reference class has a Weak Refernce object for
  
       KeyBean
, so we would assign the same object of KeyBean
created just above to            the instance of  KeyBeanParent
. A point to note here is we are not assigning any           
reference , because usage of reference queue is optional and 
WeakReference
class 
  
       provides us with 2 different constructors .
  (2)
–
We
create a new instance of Reference Queue
  (3)
–
This
is the place where we create a weak reference and attach the
previously             created  queue
  (4)
-   Now we hit first print statement , as you can compare with the
output section ,              wf.get()
returns the original object on which  this weak reference was created
            (5)
-   This is where the weak reference concept actually begins, at this
point we simply              set the reference to null and making the
referenced object only reachable through              2  weak
reference , one from wf
in the main method and one under p
(               KeyBeanParent)
object's kb
reference
 
 (6) & (7) -    At this place , we try print the
values from the respective weak references and as     you could see
from the output section that , both then returns the same object.
    This is due to the fact that GC probably hasn't run after setting
the value to null.
  (8)
-    In next step we notify GC to run explicitly ( as we understand ,
its just a      notification and doesn't ensure that GC would run ,
but in this case as the load is     least , so we notice that GC
actually run ( This
is pure co-incidence and can't     be
relied upon)
. 
 
 (9) & (10) -   Here we try to print the value from
weak references and we notice that (from     output ) section that
these values are null.  
 
   (11) & (12) -   As GC puts the weak reference
into Refrence Queue  , we can get it out using       
methods like poll and remove them and print it.
 Summarizing
Story of WeakRefrence
  Whenever
GC finds that any particular object on heap doesn't have a strong
reference or    soft reference**  but is reachable through
weak reference , then it picks up this weak    reference ,
disconnects it with the object and insert this weak reference into
the     Reference Queue (if any) . The Object now id ready for the
process of Garbage     collection.
 **
Soft Reference would be a part of next article , for now you could
assume it to be another        form of reference. 
 Why
do we need Weak Refernce
  This
answered by Java in its own SDK . WeakHashMap , is one
of the classes which    leverages this concept . As per documentation
of Java for this class , it says ,     WeakhashMap is pretty similar
to HashMap , only difference being that keys are weak    references.
  Now
the question is why do we need it – Lets take an example , If
suppose you are    loading a gif format file and we know the
size of these files can shoot up-to 5 MB . So    we  decide to keep
this object in a map with a key and value pair . Now once the use of
   this map object is over , we are responsible to remove it. Now
this is a additional    functionality we need to implement and
manage. But this could be avoided using    weakhashmap , once the GC
realizes that there is no strong reference to the key , then it
   would , internally release the weak key from the map and that gif
object is released from   memory.
 In
the next article , we would discuss about Phantom and Soft
references.
No comments:
Post a Comment