Q1. gc mechanism cannot be forced, Then what am I doing with the code System.gc() ? Is it that, I am forcing the mechanism explicitly , but cannot gaurantee the results that gc will ever run, bcos it runs in a low priority thread and may never get a chance to run. Q2. Is it that referencing an object by null will always make it ready to be garbage collected(atleast at that point or line) even if it gets another reference down in another line. For e.g : When (at what line) is Object reference s2 gced ? 1. String s1 = new String("java"); 2. String s2 = new String("gc"); 3. ... 4. ... 5. s2 = null; 6. .. 7. .. 8. .. 9. s2 = s1; 10. .. Answers: a. line 5 b. line 6 c. line 10 I think line 6. any other answers & explanations, please welcome.
eram, From your qstn, I understand that you are using a loose language for the object ref and the actual object itself. The point you have to clear first is , String str = new String("Java"); Here 'str' is object reference There is a String object allocated memory in the heap by the new String("Java"); statement. This is the object 'str' is the refence var which has the memory address of the String "Java" object.
Having said that, 1. object refs are completely different from objects . 2. The relation bet the 2 is, physical objects are referenced by object ref. 3. An object may be referenced by more than one references. For ex. String str = new String("Java"); String str1 =str; 4. But the vice versa is not true. At any time,a reference can refer to maximum only one object. Why I say maximum here is the ref can be set to null also. If set to null then the ref does not refer to any object. 5. Important point is Only objects are garbage collected NOT object references String str = new String("Java"); str = null; means the String object in the heap, which has "Java" as its content loses its referenece. No reference holds its neck. . It is free now. So this object is ready to be GC'd. (We assume that at no other point in the program, there is another reference again refers to this object). But the refernce var 'str' still exists. It can hold another object's memory address as it's content. This 'str' ref is NOT GC'd. So after all these explanations, if we see your program, The qstn MUST be changed as follows. When (at what line) is Object reference s2 gced After which line of code ,the object referenced by s1 is eligible for garbage collection ? 1. String s1 = new String("java"); 2. String s2 = new String("gc"); 3. ... 4. ... 5. s2 = null; 6. .. 7. .. 8. .. 9. s2 = s1; 10. ..
When the program thread executes these lines, at line 5 s2 ref is set to null , meaning the "gc" String object is freed now. So after this execution of this line of code finished, "gc" object in heap may be Gc'd. At line 9 s2 is assigned the same ref held by s1 var. So both reference vars hold the neck of physical String object "Java"; It doesn't matter whether ref s2 made to refer to another object or not. Once s2=null; is executed, the "gc" String object is eligible for GC. There are some other mechanism through which the before object is garbage collected, it can be made to have another ref to it.By overriding,protected finalize() throws Throwable method. But this concept doesn't come into picture here, because String class is final class . You can't subclass and override the finalize() method . So once a String object is set to 'null' means it <is eligible >for GC. There is no way to bring it back again. (unless it is a String literal in the String pool and this discussion is not needed for SCJP2 cert ) regds maha anna
Good answer M.A. (as usual). Regarding the last paragraph, I just wanted to note that for those of you interested only in certification, you don't need to worry about that. So anyone who's confused by the last paragraph, don't worry about it for now. If you're confused by the previous paragraphs though, study them carefully, because they're important to understand. As for the original question Q1: you can force part of the garbage collection mechanism to run (namely the gc() method itself), however it may abort early without going through the extensive process of finding all referenced objects in memory and then marking the unreferenced objects for deletion. And even if it does go through this process, it may not find any available memory. So basically, you can "force" the system to try to do garbage collection, but you cannot force it to get results. The low-priority gc thread is something else, unrelated to what happens when you run System.gc(). That refers to the asynchronous gc - the fact that even if there is no System.gc() call and there is no problem currently with low memory, the garbage collection will be attempted periodically by the system because there's a low-priority thread that makes it happen. If you invoke gc() directly (or if the system invoked it because it was otherwise about to throw an OutOfMemoryError) then it's not necessarily low-priority. (In the last case, it better be highest priority, since otherwise the system's about to crash.)
Maha anna, With regard to the statement: only objects are gc'd not object references. What about: ... Object o1 = new Object(); Object o2 = new Object(); Vector v = new Vector(); v.addElement( o1 ); // adds REFERENCE to vector v.addElement( o2 ); // adds REFERENCE to vector o1 = null; // object referred to not gc'able because v has reference o2 = null; // object referred to not gc'able because v has reference v = null; // v, o1, o2 objects referred to all gc'able but who knows when? Runtime.gc(); // suggests gc but who knows when? ... when v is finally gc'd aren't the object references that were the Vector instance gc'd as well? When the object that owns this code is gc'd aren't o1, o2 and v gc'd, too? Or is this a stack/heap thing that always confuses me? I'm not trying to pick nits, it just seems that on the first read the statement appears correct but the more I thought about it the more it seemed incorrect although a good explanation within the context of eram's question...the question is, how do you express that context so that the statement is correct (if it is indeed incorrect). Steve firstname.lastname@example.org
[This message has been edited by Steve Butcher (edited March 21, 2000).]
Joined: Jan 30, 2000
Steve- you are correct. I suppose to be correct we should say that variables - references and primitives - are only collected when the object or class that contains them is collected. Good point.