Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Clarification on Garbage Collection

 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
class CardBoard {
Short story = 5;
CardBoard go(CardBoard cb) {
cb = null;
return cb;
}
public static void main(String[] args) {
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
c1 = null;
// do Stuff
} }

When // doStuff is reached, how many objects are eligible for GC?


My initial thought is c1 and c3. But that's not the correct answer. Can someone explain further? (particularly why c3 is not eligible)

Thanks
 
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi.

Initially, you should pay attention to the correct terms and their meaning. c1, c2 or c3 are never eligible for garbage collection, the objects referenced by them might be though. That's why the question says "how many objects" are eligible for garbage collection. Did you get the difference?

The object allocated in the first line, referenced by c1, should be eligible for garbage collection. Because c1 is set to null and there're no other references to it. At the second line, a new object (call it obj2) is allocated and assigned to c2. Finally, the third line declares a reference c3 and assigns it to the return of method go. Since Java passes by value, this method receives as an argument a copy of the reference to obj2. Then, it sets this reference to null and returns it. Therefore, what c3 actually receives is a null reference. And c2 still is a valid reference to obj2. That's why obj2 is not eligible for garbage collection. Is it clear?
 
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi ,

I am not clear on why c3 is not eligible for garbage collection though c3 receives null reference. Is not it that c3=null hence eligible for garbage collection.

Pls. explain.

Thanks,
Konda Golamaru.
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Konda Golamaru:
Hi ,

I am not clear on why c3 is not eligible for garbage collection though c3 receives null reference. Is not it that c3=null hence eligible for garbage collection.

Pls. explain.

Thanks,
Konda Golamaru.



Objects are eligible for garbage collection -- not references. Yes, c3 is assigned the value of null, but what object was c3 pointing to prior to that? Did assigning c3 the value of null, make an object not reachable, and hence, eligible for GC?

Henry
 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
class CardBoard {
Short story = 5;
CardBoard go(CardBoard cb) {
cb = null;
return cb;
}
public static void main(String[] args) {
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
c1 = null;
// do Stuff
} }
------------------------------------------------------------------
friends its clear to you that c1(object) is null so, the object that c1 points is eligible for GC. go(c2), here the reference is only passed and not the object so the reference c2 now points to null. object which was previously assigned to c2 is not destroyed and is not eligible for GC.
but in c3 no object is created [ i mean no new CardBoard();] so c3 doesnot point to any object which is not eligible for GC.
 
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


In Java, new objects are created explicitly only when * new * is invoked. (Reason i put the term "explicitly" is when we speak someother objects out of String!).

In Line 1 & 2, there are two new objects created as they in turn have got the constructors invoked with the *new* operator. So there are two objects existing as such.

Look at Line 3. Actually there was no new object created because of not invoking the constructor explicitly. What it happens is all about calling the method "go" on the object reference "c1" by passing the object pointed by the reference "c2".

Inside the method "go", the method parameter received in the name of "cb" and only that local reference variable 'cb' is set to null and returned back. Since the same 'cb' is returned back, the changes will seem like having an impact/reflection back to the calling place.

The return value "null" is actually assigned to the reference variable c3 in line 3.

Summary:
There were only two new objects created at line 1 and line 2 and they were assigned to the reference variables c1 and c2.
As c3 does not point to any object, its of no use to consider.
After line 3, the reference variable c1 is explicitly set to NULL and there are no active references to the object being pointed by c1 as such. So that particular object alone is eligible for GC.

HtH.
 
Ranch Hand
Posts: 185
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
<B>No Object is eligible for GC.</B>

Here you are creating two objects referencing by c1 and c2.
then you are creating a copy of reference of c2 and pass it to the method. there the copy reference is null means it is not pointing to any object. so, c3 is not pointing to any object.
but, the created two objected are pointed by c1 and c2.

hope you got the point.
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Krishna,

Thats fine. But i think you have missed to see the following line

 
krishna bulusu
Ranch Hand
Posts: 185
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yup, I forgot to see the line c1=null
in that case object c1 is eligible for GC.
The answere would be "one object is eligible for GC".
Thanks Muthu.
 
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would like to bring to notice a point that most people might not even notice :

Had the value of the instance variable "Short story" been more than 127, then there would have been 2 objects for garbage collection.
[ June 12, 2007: Message edited by: Sourin K. Sen ]
 
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi I think two (2) objects are eligible for GC.

clearly one is c1 and second is "Short story = 5;", which is contained in c1 Object
 
Sourin K. Sen
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Bharat,

bytes, shorts, ints, booleans & chars exhibit immutability upto this range :

Boolean
Byte
Character from \u0000 to \u007f (7f is 127 in decimal)
Short and Integer from -128 to 127

So, in this case, since the value of the "Short story" is 5, (ie, <127), there will be only one object created for short irrespective of the number of objects created for the CardBorad class, ie, if there are 2 objects of CardBoard class, say c1 & c2, then c1.story & c2.story will be pointing to the same Short object.
Now when you null the c1 reference, it's story reference is also nulled but the Short object is still being referenced by the other c2's object. Hence it wont be garbage collected.
[ June 12, 2007: Message edited by: Sourin K. Sen ]
 
Bharat Makwana
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh again I forget it !!

Thank you Sourin for reminding it.

So there is only 1(one) Object eligible for GC, right ?


But,

I have seen this same question in Kathy and Bert(SCJP 1.5), Chapter 3, page number 267

where answer is given 2 (one is c1 and second is that Short Object), has anyone reported it ? So as per Sourin's explanation Kathy's answer is wrong right ?
[ June 12, 2007: Message edited by: Mak ]
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Sourin,


So, in this case, since the value of the "Short story" is 5, (ie, <127), there will be only one object created for short irrespective of the number of objects created for the CardBorad class.



Never been aware of such thing! Thanks a lot for pointing out this.

Can you provide some urls for more info about the same?
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think the line



is of JDK 1.5 as with autoboxing. aint I? As with JDK 1.4 its not possible to have a direct assignment.

The concept what you told also holds good with JDK 1.5 only or also with JDK 1.4 Sourin? Please clarify!
 
Sourin K. Sen
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mak:
I have seen this same question in Kathy and Bert(SCJP 1.5), Chapter 3, page number 267

where answer is given 2 (one is c1 and second is that Short Object), has anyone reported it ? So as per Sourin's explanation Kathy's answer is wrong right ?

[ June 12, 2007: Message edited by: Mak ][/QB]



Well, it's been reported in the K&B Errata. Do check it out.
 
Sourin K. Sen
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Raghavan Muthu:
I think the line



is of JDK 1.5 as with autoboxing. aint I? As with JDK 1.4 its not possible to have a direct assignment.

The concept what you told also holds good with JDK 1.5 only or also with JDK 1.4 Sourin? Please clarify!




Yes, the autoboxing concept is from Java 5.0 but the immutability like behaviour of the Wrapper classes for int & below, i think is applicable for previous versions as well though i'm not confident abt it as it's not mentioned in the K&B. Since its not pointed out in K&B as to which version this concept belongs to, I'm taking for granted that it applies to previous versions as well.
 
krishna bulusu
Ranch Hand
Posts: 185
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

So, in this case, since the value of the "Short story" is 5, (ie, <127), there will be only one object created for short irrespective of the number of objects created for the CardBorad class.


Consider the following programme:

The out put of the above programme must be 10-10 according to the above quote.
But the actuall Out put is 5-10.
could anyone explain this?
 
Sourin K. Sen
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by krishna bulusu:

Consider the following programme:

The out put of the above programme must be 10-10 according to the above quote.
But the actuall Out put is 5-10.
could anyone explain this?



If you understand immutability, then you should know that an immutable object cannot be changed.
Here, when you are re-assigning the variable, a new Short object is being created, assigned a value 10, & then its reference is stored. So, the other objects Short reference still points to the previous Short object which has a value of 5.

Hope this helps.
 
krishna bulusu
Ranch Hand
Posts: 185
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Here, when you are re-assigning the variable, a new Short object is being created, assigned a value 10, & then its reference is stored.


Let me tell you what i know from my knowledge.
in the above programme, each object of ObjectNo class will have its own s object.
so, if you change the value of s in any object , the change is not being reflected in other objects. is that true.
and in the quote, i am not assigning the 10 to any variable.
please explain.
 
Sourin K. Sen
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
krishna,
i dont want to challenge the level of your knowledge, but let me explain immutability to you properly :

Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2) System.out.println("different objects");
if(i1.equals(i2)) System.out.println("meaningfully equal");

Produces the output:

different objects
meaningfully equal


Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4) System.out.println("same object");
if(i3.equals(i4)) System.out.println("meaningfully equal");

This example produces the output:

same object
meaningfully equal

This is all because of immutability behaviour within Integer, Character, Boolean, Short & Byte.

Let's now consider the objects pointed by i3 & i4.
According to the above example, both are pointing to the same object.
now if you do this :

i3 = i3 + 1;

This will create a new Integer object, read i3's value from the previous object, add 1 to it & store it in the newly created object. The reference of this object is assigned back to i3.
Meanwhile, the reference i4 is still pointing to the previous object.

Now if you run this code again :

if(i3 != i4) System.out.println("different object");
if(i3.equals(i4)) System.out.println("meaningfully equal");

This example produces the output:

different object
meaningfully equal

And this is what is happening with your piece of code.

I hope this clears your doubt.

Oh, by the way, all this code i wrote, has been taken from K&B, chapter3, "Assignments", page 235.
[ June 12, 2007: Message edited by: Sourin K. Sen ]
 
krishna bulusu
Ranch Hand
Posts: 185
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sourin,
Thanks for your great efforts.
Let me read that chapter from K&B.
I need to upgrade to 1.5.
once again thanks.
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sourin,

Thats fine. Autoboxing is from 5.0 version only. We need to check it out whether the immutability holds good for previous versions also.

As with your example code to Krishna regdg immutability, i found one contradiction.



Are the line 1 and 2 not contradicting? I dont see any difference between the pairs {I1,I2} and {I3,I4}. But how come a check on both "equals" and "not equals" will be true?

Was it a typo or do i miss something here!? :roll:
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sourin,

I think the Immutability of Wrapper classes does NOT hold good for JDK 1.4 version. See the following program and its output. I do use JDK 1.4.2_12.



The above program produces the following output:


obj1 has (1) -> byteWrapper1 = -128, byteWrapper2 = 125, bytePrimitive = 127, stringVar = WrapperImmutableTest
obj2 has (1) -> byteWrapper1 = -128, byteWrapper2 = 125, bytePrimitive = 127, stringVar = WrapperImmutableTest

----- Effects after changing obj1's value -----

obj1 has (2) -> byteWrapper1 = 12, byteWrapper2 = 120, bytePrimitive = 122, stringVar = WrapperImmutableTest - 2
obj2 has (2) -> byteWrapper1 = -128, byteWrapper2 = 125, bytePrimitive = 127, stringVar = WrapperImmutableTest



So, with the help of above program, can we conclude that the Immutability of Wrapper holds with >127 values does not hold good only for 1.5 or above versions of Java?
[ June 12, 2007: Message edited by: Raghavan Muthu ]
 
Leandro Melo
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all.

Originally posted by harinath chakrapani:

friends its clear to you that c1(object) is null so, the object that c1 points is eligible for GC. go(c2), here the reference is only passed and not the object so the reference c2 now points to null.



Harinath, Java passes by value. So, the reference c2 does not point to null after that call. Because what is passed to the method is a copy of reference c2, which is then assigned to null.

Originally posted by Raghavan Muthu:



Are the line 1 and 2 not contradicting? I dont see any difference between the pairs {I1,I2} and {I3,I4}. But how come a check on both "equals" and "not equals" will be true?

Was it a typo or do i miss something here!? :roll:



Raghavan, this is not a contradiction. It's related to what Souring said about the value being greater than 127 (which was a nice observation by the way). Please take a look at the following code for clarification (it's the same one with different values):

 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Leandro,

Thanks for the inputs.


Originally posted by harinath chakrapani:
friends its clear to you that c1(object) is null so, the object that c1 points is eligible for GC. go(c2), here the reference is only passed and not the object so the reference c2 now points to null. object which was previously assigned to c2 is not destroyed and is not eligible for GC.



I think you have not seen the later part given by harinath. What he told is fine. Aint I?


Raghavan, this is not a contradiction. It's related to what Souring said about the value being greater than 127 (which was a nice observation by the way).



Thank you Leandro and Souring!! Thats a good point obviously. I missed to notice the difference in the values being "<127" and ">127"!!

But I dont get that immutability in JDK 1.4 version. See my previous reply for the same with the sample program. Any inputs on that? :roll:
[ June 12, 2007: Message edited by: Raghavan Muthu ]
 
Leandro Melo
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello again Raghavan.

Originally posted by Raghavan Muthu:
Hi Leandro,
Thanks for the inputs.

I think you have not seen the later part given by harinath. What he told is fine. Aint I?



Yes I did see that. I didn't quote it intentionally, because in my opinion the paragraph is self-contradictory. Harinath says that c2 is pointing to null after the call (which is wrong, as I already mention in my previous post) and then that the object (previously referenced by c2) is not destroyed and so not elligible for garbage collection. But, Destroying the object is the "product" of garbage collection! Also, following harinath's line of tought, if c2 was set to null, then the object it referenced would be elligible for garbage collection (in that case, no additional references were pointing to it). See my point?


Originally posted by Raghavan Muthu:
Thank you Leandro and Souring!! Thats a good point obviously. I missed to notice the difference in the values being "<127" and ">127"!!

But I dont get that immutability in JDK 1.4 version. See my previous reply for the same with the sample program. Any inputs on that? :roll:



That's because such immutability doesn't happen in Java 1.4. In the case of Integers, Bytes, etc, it only makes sense with boxing/unboxing, which is not available in Java 1.4. The same code we're using would be written in Java 1.4 using new Integer, which does create new objects to represent that integer. Take a look at the code below:



Is that clear now? You can also take a look here.
[ June 12, 2007: Message edited by: Leandro Melo ]
 
Raghavan Muthu
Ranch Hand
Posts: 3389
Mac MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Leandro,


Yes I did see that. I didn't quote it intentionally, because in my opinion the paragraph is self-contradictory



Yes. You were correct. Thanks for pointing it again.


That's because such immutability doesn't happen in Java 1.4. In the case of Integers, Bytes, etc, it only makes sense with boxing/unboxing, which is not available in Java 1.4.



Thats great! Thats what i have assumed as well.

But then it seems this * immutability * feature has been added to the wrapper class just because of the boxing/autoboxing facility along with JDK1.5. Is it? It does seem to be so.


Thanks again for confirming it Leandro !
 
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I ran this code.But I'm getting only "Diff object" as output.
Could anyone explain.

Integer i3 = 10;
Integer i4 = 10;
i3 = i3 + 1;
if(i3 != i4) System.out.println("diff object");
if(i3.equals(i4)) System.out.println("meaningfully equal");

Thanks,
Sumi
 
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi sumi,

what do you expect?
 
reply
    Bookmark Topic Watch Topic
  • New Topic