Java is becoming quite old (version 1.0 came out in 1996 if I’m not mistaken). When something turns old, legends, myths, and other perceived truths are quick to form around it (just imagine an old Gothic mansion with its stack of scare tales).
Most of the accumulated knowledge is beneficial and helpful, but some of it is not relevant anymore or just plain wrong.
Remembering that Java is 14 yeas old (2010), when I google for something, for Java info/answers, I always inspect the date of the article I landed on.
If you stumble upon somebody claiming that java can/can’t do something, always check his comment’s date. If I see something from 2001, you better search for newer references, instead of accepting it as is.
Some sites like http://Javaworld.com, have been there from the get go, were big then, but after losing popularity, are now a grave yard for old Java skeletons (I myself have a not that relevant article there).
The story with String.intern() is the same, you’ll find people all around the place, claiming that over using it will finish up the perm area, because the perm area is never garbage collected. As discussed here, that’s just not true.
Something I enjoy doing is not taking so called “facts” as granted, and re-validating on my IDE.
Thinking that those intern() allocations will never be GCed, I was planing a presentation on how to use weakHashMap based solution can serve as an alternative cache repository for Strings, wrote a program to demonstrate an OMME caused by intern() only to find out that intern() is not so bad as I originally thought.
Try stuff yourself. You be surprised…
Other myths I’ll should wright about some day are:
- Regular expressions in Java are slow – FALSE! I’ve tested this myself, and after compiling the regex, I was able to run over than 1 million matches per second (small strings of course).
- Always use StringBuffer to concatenate strings – dead wrong! if you have all concatenations in a single line, like the following, the compiler auto does it for you:
s= “Hi my name is: “+myName+ “. my lucky number is: “+num;
Run Javap on a class file using and not using StringBuffer to see that the byte code is the same.
Though this piece of code could benefit from StringBuffer to prevent rapid object creation:
for (…) {
s += strOfThisCycle;
}
In any case, Java5 introduces StringBuilder which is the unsynchronized tween of the synchronized StringBuffer class. I guess you will rarely access the same builder from different threads, therefore StringBuilder should be the default choice for ya.
Tags: Java, memory, multithreading
Hi,
In java 6 I think that if you run javap on the for loop example you will
see that it uses StringBuilder also, But I might be mistaken
Eyal
Eyal, you seem to be right!
I’ve checked on both IBM Java5 and IBM Java6.
Both loop and multi-lines concatenations turn into a StringBuilder.
Seems like there are less and less reasons to micro tune your code.
Thanks.
————————————————
concatenating in a loop – Javap will show you StringBuilder
————————————————
public static volatile String s = “”;
public static void main(String[] args) throws InterruptedException {
for (int i=0; i<10; i++) {
String strOfThisCycle = String.valueOf(i);
s += strOfThisCycle;
}
}
————————————————
Concatenating over multiple lines – Javap will show you StringBuilder
————————————————
public static void main(String[] args) throws InterruptedException {
String strOfThisCycle = “0″;
s += strOfThisCycle;
strOfThisCycle = String.valueOf(System.currentTimeMillis());
s += strOfThisCycle;
}
In some cases you still want to avoid String interns. Java allocates the memory to the interned strings on the permgen space. If you have a very heavy application with tons of classes (I had some like these), the classes are competing with the interned strings on the space. While the GC does clean up the permgen space, it does it only in a “stop the world” GC and not in a CMS which you typically configure your webapp or desktop to. The problem is more typical to web application where you may have very large heaps and very high object creation rate. If the GC is being called on the permgen too often it will eventually throw out of permgen space exceptions (seen it as well).
So the final answer is “it depends”
I would still recommend not to use intern in the common application though there are few edge cases where it would make sense.
I think you can enable perm gen cleaning on cms
CMSPermGenSweepingEnabled
Thanks Eyal, this is pretty cool, didn’t know about this option.