aspose file tools*
The moose likes Performance and the fly likes failed on interview-question: local String-literal causes heap-allocation (?) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Performance
Bookmark "failed on interview-question: local String-literal causes heap-allocation (?)" Watch "failed on interview-question: local String-literal causes heap-allocation (?)" New topic
Author

failed on interview-question: local String-literal causes heap-allocation (?)

Larry D. LeFever
Greenhorn

Joined: Aug 07, 2004
Posts: 6
Hi,

Yesterday (in a job-interview! -- damn it!), I learned one of the finer points of String-allocation: local String-literals cause heap-allocation.

I just checked that claim, using the -Xrunhprof option.

If I interpreted the hprof-output correctly, it showed a String-allocation if a String-literal was used but not if a static-constant String was referenced:



What I'd been thinking about the use of such a "bare literal" had concerned merely source-level maintainability.

I'd been thinking Java would just put an anonymous (i.e., implicit) temporary reference into the constant-pool onto the stack, assuming "someString" would have been put into the constant pool of the LiteralAlloc-class, upon classloading.

So, it seems I was wrong about that.

Any edifying comments from anybody about this?
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30762
    
156

Larry,
In your example, you are comparing two different strings. "someString" vs "theString". That would have an effect on the output.

In the same class file, I thought java was able to use the same memory for the string literal. We aren't supposed to rely on that when coding, but the JVM optimizes the memory. And of course for maintaining it.

Welcome to JavaRanch!


[Blog] [JavaRanch FAQ] [How To Ask Questions The Smart Way] [Book Promos]
Blogging on Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, OCAJP, OCPJP beta, TOGAF part 1 and part 2
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Not sure what you've been seeing in the profiler output, but the local string literal compiles toWhile the string constant compiles toYou see that there is zero difference between them (apart from the fact that the comparison is slightly different, of course). There is certainly no difference in string allocations.

- Peter
Larry D. LeFever
Greenhorn

Joined: Aug 07, 2004
Posts: 6
I think, now, the issue is: whence cometh that "someString"? That is, from where is it loaded (as by that "ldc" instruction)? From the constant pool or from the heap?

My thought was that it's loaded from the constant pool, so there's no added burden placed upon the garbage-collector (in particular, in cases of the method being under intense load -- as was suggested in the interview-question).

That is, I thought Java would just create a reference into the constant pool and push that; and that, then, of course, it would be "de-allocated" automatically (from the stack) and so not by garbage-collection.

The contention, by the interviewer, was, to the contrary, that the use of such a String-literal causes heap-allocation and therefore adds burden to the gc.

I believe what I saw via runhprof showed a heap-allocation. I should double-check that (though I'm at work now; that'll have to wait a while).
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Larry D. LeFever:
local String-literals cause heap-allocation.


Wouldn't that conflict with the JLS: http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#19369 ?


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Larry D. LeFever:
I think, now, the issue is: whence cometh that "someString"? That is, from where is it loaded (as by that "ldc" instruction)? From the constant pool or from the heap?
From the constant pool; that's what the ldc instruction does.
My thought was that it's loaded from the constant pool, so there's no added burden placed upon the garbage-collector [...] The contention, by the interviewer, was, to the contrary, that the use of such a String-literal causes heap-allocation and therefore adds burden to the gc.
The interviewer was simply wrong.

- Peter
Steve Quintana
Greenhorn

Joined: Aug 09, 2004
Posts: 7
Peter, I was looking up this info but couldn't find a definitive answer for it: when is the String object referred to by "someString" actually allocated? Is it when the enclosing class is loaded?

public class LiteralAlloc{
private static final String ASTRING = "theString";
public static void main(String[] args) throws Exception{
if("someString".equals(ASTRING));
// vs.
// if(ASTRING.equals(ASTRING));
}
}

Steve Q.
[ August 09, 2004: Message edited by: steveq9t4 ]
Steve Quintana
Greenhorn

Joined: Aug 09, 2004
Posts: 7
Just did a bit more reading - it seems that "someString" MAY allocate a new String object depending on whether it has been seen before. If it has not been seen then a new String object will be created on the first pass, if it has been seen then it depends on whether it has been eligible for garbage collection since that time. If it has been eligible then using "someString" may or may not cause a new String object allocation depending on whether the garbage collector has cleared it out. And, to answer my own question, the String object is allocated at runtime when the string is actually encountered, and not at class loadtime. Cheers,

Steve Q.
[ August 09, 2004: Message edited by: steveq9t4 ]
Larry D. LeFever
Greenhorn

Joined: Aug 07, 2004
Posts: 6
It seems my interviewer was right. Smart felluh.

(Good news, though, I just got email asking me to come back for the next round of interviews at that same place!)

Thanks, all, for the insights, etc.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by steveq9t4:
[...] Just did a bit more reading - it seems that "someString" MAY allocate a new String object depending on whether it has been seen before. If it has not been seen then a new String object will be created on the first pass, if it has been seen then it depends on whether it has been eligible for garbage collection since that time. [...]
If you want to be absolutely precise, the JVM may instantiate (if necessary) and intern() the String literals at class load time, or lazily when the ldc first executes. The JVM spec does not seem to favour either approach but it seems that lazy loading is the norm in JVMs. However, this is a VM implementation choice that is totally irrelevant to the question at hand. There is no difference whatsoever between the two in terms of garbage collector load.

The reason an interned String literal cannot be garbage collected is that the JVM keeps references from compile-time constants in a class (the #9 in ldc #9) to the corresponding interned String object. It may become eligible for garbage collection only when the class itself is garbage collected, which can only happen when the classloader which loaded it gets garbage collected, for example when you redeploy a web application.

The interviewer was wrong. There simply is no issue with inline String literals and garbage collection under heavy loads.

- Peter

PS. Don't trust me, though. Write code with an inline literal and try to force it to be garbage collected; you can detect re-creation by tracking its System.identityHashcode().
[ August 09, 2004: Message edited by: Peter den Haan ]
Jeroen Wenting
Ranch Hand

Joined: Oct 12, 2000
Posts: 5093
Your interviewer would be right even if the JLS said nothing about String objects existing on the heap.
After all, there's more than one kind of heap involved.
The String constant pool has to live somewhere, and that somewhere is the heap of the OS under which the JVM runs (after all, that's where the JVM will have all its allocated memory however which way it divides it up for internal use).


42
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Jeroen Wenting:
Your interviewer would be right even if the JLS said nothing about String objects existing on the heap.
Jeroen, you're missing the point here. The issue is not whether they exist on the heap - of course they do, whether they be inline (local) literals or string constants: all objects live on the heap. The issue is whether there is any important allocation difference between the inline literals or string constants, and specifically whether one or the other is preferable with regards to garbage collection behaviour under high loads.

The interviewer's contention was - and tell me if I'm wrong here, Larry - that constants are preferred over inline literals because the latter will cause object churn under load. My contention (and Ilja's) is that this is not true at all, and there's no reason whatsoever to prefer one over the other from a performance point of view.

- Peter
[ August 10, 2004: Message edited by: Peter den Haan ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Hi Steve,

welcome at the Ranch!

We don't have many rules here, but there is one we attach some importance to: our Naming Policy.

I'd therefore like to ask you to change your display name according to it, specifically to make it look like a real name. The above link tells you how to do that.

Thank you very much, and have fun at the Ranch!
Larry D. LeFever
Greenhorn

Joined: Aug 07, 2004
Posts: 6
Are you all familiar with this?

Inlined Constants
Mastering the Fundamentals of the Java Programming Language

http://www.sys-con.com/story/?storyid=37992

I found it via google. Then, I went to the site for the book entitled "Java Rules", by the same author, Doug Dunn.

Interestingly, that site points back to JavaRanch!

-----

Definitely "Java Rules" is my favorite book on Java, and there is nothing it can be compared to!
...
Margarita Isayeva (this is my real name
co-author of "Mike Meyers' certification Passport Java 2"

[Author's Note: Margarita is a "Sherriff" at the Java Ranch. You can read her bio there. ...]

-----

Anyway, it seems, all in all, there is an allocation occuring in the code in question, but that, then, the String is being interned and is consequently not eligible for gc until the class it's cited in is eligible.

So, I guess I was partly right and partly wrong: right, in that the bare String-literal does not cause a significant gc-problem; wrong, in that there is, evidently, nevertheless, an allocation that occurs -- at least in some JVMs (?).

I hadn't posted to RavaRanch in a long while. I'd first encountered it back in the year 2000 (approx.), back when I was seeking Certification Exam help. It's pretty consistently provided me with valuable feedback, as in this case.

Thanks again, all, for your feedback.
Steve Quintana
Greenhorn

Joined: Aug 09, 2004
Posts: 7
Sorry about the name folks, I have now updated it. By the way, I think we all pretty much agree on the answer to the original question. One other thing we also likely agree on is that it is not a very good question to be asking in an interview Enjoyed the discussion though, cheers...

Steve Q.
Steve Quintana
Greenhorn

Joined: Aug 09, 2004
Posts: 7
Peter, I was also curious about your comment "If you want to be absolutely precise, the JVM may instantiate (if necessary) and intern() the String literals at class load time, or lazily when the ldc first executes. The JVM spec does not seem to favour either approach but it seems that lazy loading is the norm in JVMs."

I would be suprised if lazy loading was used since it is imposing a hit that may be unnecessary if the code that uses the literal is not actually executed. It seems to make more sense that instantiation would be done on an as-needed basis to minimize the class load time. Please correct me if I'm wrong, Java performance issues are something I am becoming increasingly interested in. Thanks,

Steve Q.
Jean-Claude Dufourd
Greenhorn

Joined: Aug 10, 2004
Posts: 1
On the relevance of the question in the context of an interview, it looks like this interviewer read the Guerilla Guide to Interviewing, by Joel Spolsky (http://www.joelonsoftware.com/articles/fog0000000073.html).

This question really feels like "3. Impossible Question"

No ?

Best regards
JC
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Steve Quintana:
Sorry about the name folks, I have now updated it.


No problem, thanks!

One other thing we also likely agree on is that it is not a very good question to be asking in an interview


Would leave me wondering why the interviewer cares about it, at least...
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Jean-Claude Dufourd:
On the relevance of the question in the context of an interview, it looks like this interviewer read the Guerilla Guide to Interviewing, by Joel Spolsky (http://www.joelonsoftware.com/articles/fog0000000073.html).

This question really feels like "3. Impossible Question"

No ?


I don't think so - there is not much creativity in answering the question, only stupid knowledge of the innards of the VM you will likely never need in practice (Unless it was an interview for a programming position in very tightly constraint environments, of course). The only answer that comes to my mind is "can I have a look into the JLS, please?"
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Larry D. LeFever:
[...] Interestingly, that site points back to JavaRanch! [...] Margarita Isayeva (this is my real name
co-author of "Mike Meyers' certification Passport Java 2"
Incidentally, a book that I was tech editor for. The plot thickens

- Peter
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Steve Quintana:
I would be suprised if lazy loading was used since it is imposing a hit that may be unnecessary if the code that uses the literal is not actually executed. It seems to make more sense that instantiation would be done on an as-needed basis to minimize the class load time.
Yes. That's what I meant by lazy loading - instantiating and intern()ing them all at class loading time I would describe as eager loading. Apologies for not keeping my terminology unambiguous.

- Peter
Steve Quintana
Greenhorn

Joined: Aug 09, 2004
Posts: 7
Ok, no problem, much thanks for your help. Cheers,
Steve Q.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: failed on interview-question: local String-literal causes heap-allocation (?)