• 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • paul wheaton
Saloon Keepers:
  • Ganesh Patekar
  • Frits Walraven
  • Tim Moores
  • Ron McLeod
  • Carey Brown
Bartenders:
  • Stephan van Hulst
  • salvin francis
  • Tim Holloway

garbage collection  RSS feed

 
Ranch Hand
Posts: 280
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Consider the following code:
1. public void method(String s){
2. String a,b;
3. a = new String("Hello");
4. b = new String("Goodbye");
5. System.out.println(a + b);
6. a = null;
7. a = b;
8. System.out.println(a + b);
9. }
Where is it possible that the garbage collector will run the
first time?
(after line 6 the object which was referenced by a would be eligible for gc.)
My doubt is:
will this System.out.println(a + b); be the first line
after which gc could run?Is it that a+b creates a new String which ie now referenced by none??
Thanx in advance
 
Ranch Hand
Posts: 418
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Leena,
u can never say that, after such and such line gc could run! it may or may not.
The object referenced by 'a' will be eligible for gc after it is set o null.ie. after line 6. So gc may run but not surely!
Rashmi
 
leena rane
Ranch Hand
Posts: 280
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanx Rashmi for replying,
but
what my doubt is:
after which line gc could probably run first.
after 5
or
after 6

 
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
at line 7 the object ref. by a is eligible for gc but u can never be sure when it will be since gc is a very low priority thread.
i hope this hels.
Jennifer.
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The garbage collector will only run if there is memory shortage, or System.gc() is called and it happenes to run.
I think that in line 5 there are a StringBuffer and String(not a or b) used in the concatenation operation that are no loger referenced.
Besides, in line 6 the String Hello looses its reference
 
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
IMO
after 5 th, line the string created by a+b will be eligible for gc.
After 6 th line the object referenced by a will be eligible for gc .
After 8 th line the new string created by a+b will be eligible for gc.
THANKS.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
to Bindesh
Don't forget the StrinBuffer objects used for the concatenation ;-)
 
Bindesh Vijayan
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Could'nt quite understand Jose. Please explain.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am sorry Bindesh I couln�t answer before because I was offline. In fact I was studying Java.

Thought the following is implementation dependant String concatenations are performed like this:
A)creation of a StringBuffer
B)addition of the strings to the StringBuffer
c)toString() is invoked on the StringBuffer
I fed a simpler example to javap for showing these steps.

this is the ouput

You can see that the sequence of methods invocations match the previous steps
 
Bindesh Vijayan
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jose.
I understood the internal working.But I want you to tell me was i wrong with my answer.I can't get the reason bcoz to me whent a stringbuffer obj is created that too becomes eligible for GC after print statement.Please clear it.
THANKS
[This message has been edited by Bindesh Vijayan (edited September 08, 2001).]
 
Ranch Hand
Posts: 201
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Look at the following code--
1)String Str = "JavaWorld";
2)str=null;
How many objects are eligible for GC here at line 2..?
Thanx
 
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi swati,
According to me,"JavaWorld" is a String literal and since it is created in StringPool and not in the Heap it will not be eligible for G.C
let me know if i am wrong.
rajashree.
 
Ranch Hand
Posts: 236
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Hi All,
Couple of interesting points there regarding the involvment of StringBuffer objects while concatination!!.

But my point is that,
ultimately the toString() method is called which returns the
a String object encapsulating the appended StringBuffer objects.
So even now the original point still holds good that GC is likely to happen after line 5(i,e after concatination).
Any further views?
Manjunath
 
Bindesh Vijayan
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is what I said
Manju.
 
swati bannore
Ranch Hand
Posts: 201
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
U r right ,Rajashree
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
>to Bindesh
>Don't forget the StrinBuffer objects used for the concatenation ;-)
I wrote that because you didn't mention StringBuffer here
>MO
>after 5 th, line the string created by a+b will be eligible for >gc.
>After 6 th line the object referenced by a will be eligible for >gc .
>After 8 th line the new string created by a+b will be eligible
>for gc.
I put ;-) because I understand it is implementation dependant (other VM coul not use a StrinfBuffer for concatenation) and thus not required to be known.
to Rajashree
I think all objects are created in the heap.
String literals are added to a pool of strings. I don't know if adding a reference to the String object or the pool itself is in the heap. But once this has happened the string object is never unreacheable because it is still in the pool; and this pool is going to be used for the duration of the program.
This progrma shows that a string literal is not garbage collected:

it prints
java.lang.ref.WeakReference@111f71
null
 
Bindesh Vijayan
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's all OK.But I need you to tell me whether I was wrong with my answers.Since now you have created doubt in my mind.
THANKS.
 
leena rane
Ranch Hand
Posts: 280
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanx all for replying,
points raised by
Manjunath Subramanian and Bindesh Vijayan
is exactly where i have my doubts.
I suppose the StringBuffer is converted to String.
quite confused ??
also

class Test {
String a = "hola", b= "adios";
Test (){System.out.println(a + b);}
}

Jose, here u have used literals instead of String objects,
will that a difference in the answer for this question.
Also can u tell me in short how and when javap should be used.
(I guess it is used to understand what happens behind the scenes)
thanx in advance.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
>points raised by
>Manjunath Subramanian and Bindesh Vijayan
>is exactly where i have my doubts.
>I suppose the StringBuffer is converted to String.
>quite confused ??

Hi Leena
The StringBuffer object is not converted to a String but a new String is created for holding the contents of the StringBuffer
In the API for StringBuffer.toString() it can be read that.

>class Test {
>String a = "hola", b= "adios";
>Test (){System.out.println(a + b);}
>}
>Jose, here u have used literals instead of String objects,
>will that a difference in the answer for this question.
Being the question when objects pointed by a and b variables become unreachable yes, it makes a big difference, because
as my last posted program shows String literals are never garbage collected.
Very briefly: once Test.java is compiled "javap -c Test" can show the compiled bytecodes -fortunately translated into VM instruccions-
The documentation for the java tools in the SDK explains more on javap.
For learning about the bytecodes I recommend Inside the Java 2 Virtual Machine by Bill venners. You can read some chapters free on line at artima.com
Anyway as javap shows which methods the JVM invokes sometimes a great knowledge about bytecodes is not needed.
hope helps
 
rajashree ghatak
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Jose,
will u plz tell me whether what i replied to swati's Ques is correct or not.
rajashree.
 
leena rane
Ranch Hand
Posts: 280
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by rajashree ghatak:
hi swati,
According to me,"JavaWorld" is a String literal and since it is created in StringPool and not in the Heap it will not be eligible for G.C
let me know if i am wrong.
rajashree.


Are u asking for this,
this is absolutely correct
 
rajashree ghatak
Ranch Hand
Posts: 151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanx leena for the reply.
 
Bindesh Vijayan
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jose,
Look at this line in bytecode
19 new #7 class java.lang.StringBuffer
Don't you think a new StringBuffer object is created.This means that in the original program of Leena at line no. 5 we have two objects for garbage collection:
1) given by toString()
2)implicit StringBuffer()
This is elegible for Gc bcoz as soon as the println statement is over it is no more referenced by any active links.
Similar is the case at line no.8
Your comments(witness) please
THANKS.
 
leena rane
Ranch Hand
Posts: 280
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How many String objects are created in
the following code?
1. String A, B, C;
2. A = new String("1234");
3. B = A;
4. C = A + B;
The answer the book gives is 2,
i.e a+b does create a new String,
here c references to a+b
but in our problem
System.out.println(a + b);
i suppose none refers to it.
Can someone give me a final conclusion to this discussion.
 
Bindesh Vijayan
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Leena do believe what Jose says, there is one new string created when a+b is done.
c=a+b;
here a+b returns a new String whoose reference is stored in c,thus we have 2 strings object created.
But even if a+b were left unreferenced as in our case System.out.println(a + b);
then too we have new string created.And I here completely agree with Jose.
But i did found out a new thing which i was referring in my previous post.So that is only the doubt existing.
Thanks.
[This message has been edited by Bindesh Vijayan (edited September 10, 2001).]
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
to Bindesh:
>Look at this line in bytecode
>19 new #7 class java.lang.StringBuffer
>Don't you think a new StringBuffer object is created.
Yes it is
>This means that in the original program of Leena at line no. 5 >we have two objects for garbage collection:
>1) given by toString()
>2)implicit StringBuffer()
This is what I thougth, but now I think both objects (String and StringBuffer) are the same because the StringBuffer is really converted to the String Object. So not a new String Object is created. Please read on...

>this is elegible for Gc bcoz as soon as the println statement is >over it is no more referenced by any active links.
>Similar is the case at line no.8
Yes whether one or two objects are created for performing the concatenation, they/it are/is eligable for being garbage collected after the execution of the println statement

to leena:
Yes I aggree, A and C (pointing to the string resulting from the concatenation) are created.

New Post New Thougths ;-)

This is from the StringBuffer API:
String buffers are used by the compiler to implement the binary string concatenation operator +. For example, the code:
x = "a" + 4 + "c"
is compiled to the equivalent of:
x = new StringBuffer().append("a").append(4).append("c")
.toString()


In line #19, in the bytecode listing, a new StringBuffer is created. In line #23 the constructor for this object is called. Let's compare with the previous sentence where a new StringBuffer is created, and the necessary append invocations have taken place. I line #30 and #37 the append invocations happen.
In the previous sentence the last call is toString and this is reflected in line #40.
So the compiler mathes what the Api tell us.
The point is does the toString method create a new String?
In the bytecodes you'll see that is the toString method of the String class the one that is called. I expected the one from the StringBuffer to be called because the append method return a StringBuffer object. This is a fact. But I don�t understand why this happens. This is the point where I have a doubt. I will be asking for help in the Sun forums and I will post the results here.
Anyway the fact is that the toString method from class String is called so this is what the API tell us:
public String toString()
This object (which is already a string!) is itself returned.

So clearly this returns the same reference to the StringBuffer object produced by the last of the append methods (line #37). Why? because this method was called on that reference as can be inferred from the line #40, and from the explanation that the API give about how a StringBuffer is used for concatenation (the sentence beginning with an x)
Summing up though a StringBuffer is created for concatenation, there is no need for creating two (a String and a StringBuffer), but the same StringBuffer is converted to the String resulting of the concatenation.


 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
New Post New Thoughts ;-)
Hey rewind all I said in my previous post. I think there is a bug in javap that made me think that. (or I have just drunk two much steaming old good Java coffee ;-) )
First of all, it is not weird that a call for a method on an object of type StringBuffer ends up in a call for method in a non hierarquical related class as String is ?
I thought the complier looked for the method to invoke in the type and supertypes of the variable that helds the reference. Later the dynamic binding magic can ocurr.
Besides, if an object of a type could receive methods from another non-hieraquical-related type we would have encountered a flaw in the type checking with which Java reassure us.
In http://usuarios.tripod.es/JoseBotella there is available a free nice though bare-bone class file parser. I fed the parser with the class file spawned from the following program:

the result can be checked by anyone:
--------------------------------------------------------
10 atag(6)CONSTANT_Methodref
0 0 class_indexjava/lang/StringBuffer
3 3
0 0name_and_type_index toString()Ljava/lang/String;
22 16
--------------------------------------------------------

what the hell is this?
This is the constant pool entry number 6. It contains a symbolic reference for a method called toString that takes no argument and it returns a String. But this method is defined in the class StringBuffer.
Now the output for the previous program produced by javap:
Method Test()
0 aload_0
1 invokespecial #1 Method java.lang.Object()
4 getstatic #2 Field java.io.PrintStream out
7 new #3 Class java.lang.StringBuffer
10 dup
11 ldc #4 String "a"
13 invokespecial #5 Method java.lang.StringBuffer(java.lang.String)
16 invokevirtual #6 Method java.lang.String toString()
19 invokevirtual #7 Method void println(java.lang.String)
22 return

In line #16 javap reports that the constant pool entry 6 is the toString method from the String class. This is in contradiction with all the previous stuff.
I have checked it also with the following program:

And the same discrepancy happens.
So it seems to me that javap has a bug here.
I think we should postpone our discussion untill we have checked this.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
New Post New Thoughts
I made an error interpreting the line
40 invokevirtual #10 Method java.lang.String toString()
This describes a method named toString() that returns a String not a toString declared in class String. I am sorry for that.
The class file parser shows that the method called is the one declared in StringBuffer class.
40 invokevirtual #10 Method java.lang.String toString()
This what the API tell us about this method:
" Converts to a string representing the data in this string buffer. A new String object is allocated and initialized to contain the character sequence currently represented by this string buffer. This String is then returned. Subsequent changes to the string buffer do not affect the contents of the String.
Implementation advice: This method can be coded so as to create a new String object without allocating new memory to hold a copy of the character sequence. Instead, the string can share the memory used by the string buffer. Any subsequent operation that alters the content or capacity of the string buffer must then make a copy of the internal buffer at that time. This strategy is effective for reducing the amount of memory allocated by a string concatenation operation when it is implemented using a string buffer."
So I think it is clear (at last) that two objects are created for concatenation, a StringBuffer and the String returned by this method.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!