14 Replies Latest reply on May 13, 2012 4:22 PM by rp0428

    Memory De-allocation

    873902
      Hi All,

      I am trying to figure out when does garbage collector collects a free object.

      As you could see in the below sample code , I have created a object of type KeyBean( a POJO with no finalize method) inside a try catch . Now when I come out of the try catch , I expect the object to be garbage collected ( as it is already finalized and available for GC and its in Block scope) .

      To test that , I created heap snapshot after ever System.gc (using JMAP) and analysed the heap (jHAT) . But even till the end of the program , there was 1 instance of keybean available , which was not up to my expectation.

      I understand , that it take a 1-2 GC cycle to free a memory space , but as per my code , instance was never removed.

      Please let me know , if I am missing some concept here




      public class SimpleAllocationTest {

           public static void main(String[] args) {

                
                try
                {
                     KeyBean kb=new KeyBean();
                     
                     
                }
                finally
                {
                     
                }
                
                
                try {
                     Thread.sleep(10000);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
                
                System.gc();
                
                System.out.println("Garbage Collected");
                
                try {
                     Thread.sleep(10000);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
                
                System.gc();
                
                System.out.println("Garbage Collected round 2");
                
                try {
                     Thread.sleep(10000);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
                
                System.gc();
                
                System.out.println("Garbage Collected round 3");
                
                try {
                     Thread.sleep(10000);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
                

           }

      }


      Thanks

      Edited by: javabee on May 12, 2012 9:28 PM
        • 1. Re: Memory De-allocation
          931373
          If you want more precise results, you may add much more instances of your object!
          The thing is gc collects unwanted objects when memory is needed. so, in order to do that, you must fill up you memory with objects.

          while doing that, you can use JConsole (which can be found in java installation path) to monitor whats happening to your application.
          • 2. Re: Memory De-allocation
            EJP
            I am trying to figure out when does garbage collector collects a free object.
            You can't, because it isn't specified. It may never happen at all. The only guarantees you have are that if the object is reachable it won't be collected, and that if you get an OutOfMemoryError, garbage collection has already freed everything possible. But I haven't seen one of those for years.
            • 3. Re: Memory De-allocation
              Nitin Khare
              You surely can't predict when GC will kick in to free up memory. Calling System.gc() may only suggest JVM to start GC but it is not guaranteed that GC will free up memory. For any object to become eligible for reclamation by GC typically it has to be not reachable by the thread which created that object unless you have used SoftReference or WeakReference from java.lang.ref package. Any reference to an object is said to be a strong reference if it has not been created using SoftReference or WeakReference.

              In your code you may try by creating more instances or make the strong reference null
              KeyBean kb=new KeyBean();
              ..
              //make (strong) reference null 
              kb=null;
              //or point (strong) reference to some other object to make old KeyBean object unreachable
              kb=new KeyBean();
              ..
              //try invoking System.gc()
              ..
              but again it can't be said even after doing this that GC will come into picture. It may or may not act.

              Hope it helps.
              • 4. Re: Memory De-allocation
                873902
                Thanks for the response ,

                But i just figured that if I modify my try block , i.e. add kb=null ( as show below ), the heap trace after first gc shows 0 instance of KeyBean . So what happens suddenly ? Still there is enough memory for JVM and I am not where reaching Out of memory stage , but this time GC some decides to remove that object. I was able figure it out using JHAT , which showed 0 instance of Keybean.

                try
                {
                               KeyBean kb=new KeyBean();
                               kb=null;
                               
                }
                finally
                {
                }


                Thanks

                Edited by: javabee on May 12, 2012 10:50 PM
                • 5. Re: Memory De-allocation
                  873902
                  Thanks Nitin, But as i mentioned , its in a block scope . Once try block is over , there is no strong reference to the object . And I don't have any weak , soft or phantom reference for that object.

                  Edited by: javabee on May 12, 2012 10:53 PM
                  • 6. Re: Memory De-allocation
                    EJP
                    For any object to become eligible for reclamation by GC typically it has to be not reachable by the thread which created that object
                    Completely incorrect. It has to be not reachable via any thread. The thread that created it doesn't even have to still be in existence for it to be reachable.
                    • 7. Re: Memory De-allocation
                      EJP
                      But i just figured that if I modify my try block , i.e. add kb=null ( as show below ), the heap trace after first gc shows 0 instance of KeyBean . So what happens suddenly?
                      So it got garbage collected. It can happen any time, or not at all. The only guarantee is the one I gave, and I guess the guarantee that reachable objects are not collected.
                      this time GC some decides to remove that object.
                      It can do that any time. Nobody has said different.
                      • 8. Re: Memory De-allocation
                        873902
                        Thanks Again,

                        But I am not sure about weak reference . Once I remove the strong reference to the object which also has a weak reference and do a System.gc () and take a snapshot of JVM heap , It clearly shows that number of instance of the bean is 0 ( which had strong and weak reference) , where as I haven't still de-queued the weak reference from ReferenceQueue. And if we inspect the weak reference in the queue , the referent section also shows it as null ( indicating that the object has been cleared).

                        Where as in phantom reference case , I can still the object to be alive after I de-queued the phantom reference from Queue.

                        Thanks
                        • 9. Re: Memory De-allocation
                          EJP
                          This is all exactly as described in the Javadoc. It's not clear to me that you've read it.
                          • 10. Re: Memory De-allocation
                            873902
                            Totally Agree

                            But the line mentioned in your previous post

                            ' It has to be not reachable via any thread, or as you say via a SoftReference or WeakReference from java.lang.ref package'

                            made me feel that , you are trying to say , that a object can't be reclaimed if it has Weak reference . I was trying to say that object can be reclaimed by GC even if it has a Weak reference attached to it , Only condition being it shouldn't have a Strong reference . It would just make the referent object of this weak reference to be null .

                            Please correct me if my understanding was wrong

                            Thanks
                            • 11. Re: Memory De-allocation
                              EJP
                              you are trying to say , that a object can't be reclaimed if it has Weak reference.
                              If I've said anything that disagrees with the Javadoc I retract it.
                              I was trying to say that object can be reclaimed by GC even if it has a Weak reference attached to it,
                              If that's what the Javadoc says, I agree.
                              Only condition being it shouldn't have a Strong reference . It would just make the referent object of this weak reference to be null.
                              Please correct me if my understanding was wrong
                              No. This is a completely stupid process. You should be learning this stuff directly from the Javadoc, not from a forum. You can see for yourself how confusing and how slow a process that is. If you find anything in the Javadoc you don't understand, or that doesn't appear to agree with your observations, ask here. Roaming the Internet collecting disagreements with the Javadoc is a complete waste of everybody's time.
                              • 12. Re: Memory De-allocation
                                873902
                                Java Doc , doesn't say when would a object will be reclaimed from memory ( as you already correctly mentioned that the reclaiming of object space is left to GC and its hard to predict) . If you look at the java docs for weak reference and phantom references, they say something like

                                then at that time or at some later time it will enqueue the reference

                                All the conclusions I am making , is after reading those docs and running small programs with analyzing heap dump and thread stack dump.

                                Apologize , if I took this thread to a wrong state .

                                But thanks again for clarifying my doubt as you have always done.

                                Thanks
                                • 13. Re: Memory De-allocation
                                  EJP
                                  Java Doc , doesn't say when would a object will be reclaimed from memory
                                  I agree. Nothing does. It isn't specified. I've already told you that.
                                  (as you already correctly mentioned that the reclaiming of object space is left to GC and its hard to predict).
                                  I didn't say that at all. It is impossible* to predict.
                                  If you look at the java docs for weak reference and phantom references, they say something like "then at that time or at some later time it will enqueue the reference"
                                  Agreed. That's what it says. Your point?
                                  All the conclusions I am making
                                  You don't have to make any conclusions. Just read the Javadoc. You haven't found anything that departs from the specification. So the purpose of this thread remains a mystery.
                                  • 14. Re: Memory De-allocation
                                    rp0428
                                    >
                                    All the conclusions I am making , is after reading those docs and running small programs with analyzing heap dump and thread stack dump.
                                    >
                                    And that is exactly why any such conclusions you draw based on doing that are unreliable at best and could be just plain wrong at worst.

                                    There has been no mention in the thread of the Java Language Specification but it is this specification that defines the language and that 'constrains' what can be done by implementations.
                                    http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf

                                    If you search the spec for the word 'garbage' there are not that many references. The ones of note are on page 3:
                                    >
                                    Objects
                                    can declare a finalize method that will be invoked before the objects are discarded
                                    by the garbage collector, allowing the objects to clean up their state.
                                    >
                                    where the key words are 'will be invoked'

                                    This important reference at the bottom of page 4 and top of page 5
                                    >
                                    When an object is no longer referenced, it may be reclaimed by the garbage
                                    collector. If an object declares a finalizer, the finalizer is executed before the object

                                    INTRODUCTION Example Programs 1.2
                                    5
                                    is reclaimed to give the object a last chance to clean up resources that would not
                                    otherwise be released. When a class is no longer needed, it may be unloaded.
                                    >
                                    Note the words 'may be reclaimed', 'fininalizer is executed', 'may be unloaded.'

                                    Then on page 332, Section 12.6 Finalization of Class Instances
                                    >
                                    Before the storage for an
                                    object is reclaimed by the garbage collector, the Java virtual machine will invoke
                                    the finalizer of that object.
                                    >
                                    Again words 'will invoke the finalizer'. This section also mentions that for large objects there may be multiple finalizers used with each one running in its own thread.

                                    That same section discusses weak references
                                    >
                                    The package java.lang.ref describes weak references, which interact with
                                    garbage collection and finalization. As with any API that has special interactions
                                    with the Java programming language, implementors must be cognizant of any
                                    requirements imposed by the java.lang.ref API. This specification does not
                                    discuss weak references in any way. Readers are referred to the API documentation
                                    for details.
                                    >
                                    The next section, 12.6.1 Implementing Finalization, does just what it says and talks about reachable versus unreachable.

                                    Because the first excerpt from the spec
                                    >
                                    When an object is no longer referenced, it may be reclaimed by the garbage collector.
                                    >
                                    means that objects are not required to be collected at all. An implementation can collect them and different implementations can use different methods for collecting them.

                                    So any conclusions about garbage collection you reach by testing your specific 'implementation of the spec those conclusions may not be valid for other JVM implementations.