• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

GC on Strings in Literal Pool

 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys, I wanted to further tighten up my notes on the subject of GC and strings in the literal pool. I know Val touched on this earlier, but I need to make sure I'm on the right track
Case 1:

Case 2:

if one of my friends could show me where I'm wrong on this, I'd greatly appreciate it.
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Paul Salerno:
Hi guys, I wanted to further tighten up my notes on the subject of GC and strings in the literal pool. I know Val touched on this earlier, but I need to make sure I'm on the right track
Case 1:

Case 2:

if one of my friends could show me where I'm wrong on this, I'd greatly appreciate it.

In your second example, until the method ends, you still have two references to the object originally created and assigned to rg. The second and third lines assign the references inside the 2D array dg to reference that object. Therefore, that object can't be garbage collected until either the references inside dg are assigned something else or the reference dg is assigned something else or goes out of scope.
I hope that helps,
Corey
 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I can see how this dg matrix holds two rg objects. Nevertheless since rg is set to null, the return value would be null, no?
Could you tell me if Case 1 is correct?
 
Duncan Allen
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey Paul,
I dont know if this helps... but
I find that the easy way to determine if an object is eligible for garbage collection is to write out the Objects created and their references.
In your second case posted here (correct me if i am wrong) but you have created three references to the Integer(3) object you created.
ie
rg---------pointsTo---Integer(3)
dg[0][1]---pointsTo---the same as above
dg[0][0]---pointsTo---the same as above
so... setting rg to null, the object (Integer(3))is still being used by your dg references (ie no GC).
Dont know if it helps, but i thought i might add my two cents.
Bonne Chance
 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Duncan and Corey, yes that does make sense.
Im still not 100% on case 1 yet, if anyone knows.
 
Rob Ross
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
S = "Kanga" + "Roo"
Both "Kanga" and "Roo" are String literals, ie, String object in the literal pool, and so will never be GC'd. However, the concatenation is NOT a literal. String concatenation is performed using a StringBuffer. After the StringBuffer does the concatenation, it's value is returned via a toString() call, which creates a new String and assings a reference to it in variable S. So now S holds a brand new String object, that is NOT in the string pool, so when S goes out of scope or gets set to null, this new String will be eligible for GC.

primative are NOT objects; they are NEVER GC'd.
However, you are correct that when you instantiate a new int[], the previous int[] is eligible for GC.
 
Graeme Brown
Ranch Hand
Posts: 193
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Rob Ross:
S = "Kanga" + "Roo"
Both "Kanga" and "Roo" are String literals, ie, String object in the literal pool, and so will never be GC'd. However, the concatenation is NOT a literal. String concatenation is performed using a StringBuffer.


No. Stringbuffer is only used if one of the Objects to be concatenated is on the heap. In the case of "Kanga" + "Roo" both of these are in the literal pool so the resulting concatenated String can be evaluated at compile time and also placed in the literal pool.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello
Graeme is almost totally right.
The concatenation of literal strings is considered by the compiler as a constant expression with a value known at compile time. Thus the content of the concatenated string is placed in the constant pool.
To find out when this can be done read JLS 15.28
Be careful the constant pool is not the string pool. The constant pool holds the content of the String. There, the string is not an object, because objects only exist in the heap. The first time the virtual machine uses the entry in the constant pool it resolves it. In this process creates the string object, this time in the String pool in the heap.
To clear this kinds of doubts use javap -c MyClass

In line 7 there is "ldc #3". This bytecode pushes into the operand stack a reference to the String object that will be created when the virtual machine creates a string object that contains the same information that the entry number 3 in the constant pool holds.
The virtual machine resolves entry 3 in the constant pool, at least, before the first time it access the entry. In this program only line 7 uses the entry.
However

Because JLS 15.28 tell us that this concatenation is not a constant expression with a value known at compile time, the compiler can not create a cosntant pool entry for storing its content. Thus a StringBuffer is created.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul, don't worry about string literals recollection because this is not a subject for the exam.
In case you are curious this post shows how string literals can be g.c.ed
 
Rob Ross
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Graeme Brown:


No. Stringbuffer is only used if one of the Objects to be concatenated is on the heap. In the case of "Kanga" + "Roo" both of these are in the literal pool so the resulting concatenated String can be evaluated at compile time and also placed in the literal pool.


<rob slaps his forehead>
Yea, that's right. I knew that though. Honest. My brain just forgot to remind me that I knew it when I wrote that.

[ February 26, 2002: Message edited by: Rob Ross ]
 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
you guys are awesome, thanks
 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is this the same situation?
Here 4 string literal objects are created within a for loop and GC'd since temp is a local var.
 
Rajinder Yadav
Ranch Hand
Posts: 178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob, I beg to differ, a statement like
String S = "Good" + "bye";
will creates 3 string in the runtime constant pool, namely: Good, bye, Goodbye
only strings created using the new operator will be GCed
Compile and run the following code to see for yourself!

[ February 28, 2002: Message edited by: Rajinder Yadav ]
 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does anyone have a clue about the last piece of code that I posted.
4 string objects are being created and I wanted to be sure that they WILL be GC'd.
TIA
 
Rob Ross
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are correct that 4 new objects are created, and they are all eligible for gc when the loop ends.
But they're not string literals.. only the string in quotes is a literal ("Hello"). If they were literals, they couldn't be garbage collected now could they!?
The new objects are String objects created via the String concatenation operator , "+".
But yes, they all are eligible for gc when the loop ends.
 
Graeme Brown
Ranch Hand
Posts: 193
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Rob Ross:

But yes, they all are eligible for gc when the loop ends.

True, but to be precise, each Object will be available for gc as soon as the assignment is made in the next iteration of the loop.
 
Junilu Lacar
Bartender
Posts: 7595
53
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Rajinder Yadav:
Rob, I beg to differ, a statement like
String S = "Good" + "bye";
will creates 3 string in the runtime constant pool, namely: Good, bye, Goodbye
[ February 28, 2002: Message edited by: Rajinder Yadav ]

Rajinder,
I think you have made the wrong conclusion there: only one String literal gets added to the string pool as a result of the code given:
String s1 = "Good" + "bye";
String s2 = "Good" + "bye";
String s3 = "Goodbye";
(s1 == s2) and (s1 == s3) are both true.
If you'd like further evidence, running this code through the javap utility will give:
0 ldc #3 <String "Goodbye">
2 astore_1
3 ldc #3 <String "Goodbye">
5 astore_2
6 ldc #3 <String "Goodbye">
8 astore_3
The compiler is smart enough to concatenate "Good" and "bye" at compile time since it can determine that the RHS is a constant string expression.
Junilu
[ March 01, 2002: Message edited by: Junilu Lacar ]
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic