jvm optimisations for string variables in methods
In a project that I am maintaining, I found a java class with a method "fn" similar to one shown below
class Test{
public void fn(){
String METHOD_NAME = "fn";
...
sysout("In " + METHOD_NAME);
}
}
The program runs indefinitely and the method 'fn' is called continuosly and at very high frequency. The question is
- would the variable METHOD_NAME get created every time fn() is called?
- would the JVM do some optimization so that the variable METHOD_NAME is not garbage collected and reused the next time fn() is called?
- would there a performance improvement if I made the variable a public static final? (Actually there are so many su开发者_开发技巧ch functions that I want to know if its worth it to change all of them)
(I guess the string pool plays some role here)
Thanks, Kiran Mohan
Yes, the variable METHOD_NAME
will be created each time you enter the method, but that's a very, very cheap operation (in fact creating 2 variables is as expensive as creating 1).
The value (i.e. the String
object) "fn"
will not be recreated, but will come from the constant string pool.
However, the expression "In " + METHOD_NAME
will be recomputed and cause a new String
object to be created each time, because it is not a compile time constant expression.
If METHOD_NAME
where static final
, then that expression as well would be a compile time constant and thus would come from the constant pool.
Variables aren't garbage collected - objects are.
"fn" is a string literal, so it will be interned. It won't be garbage collected (at least while that ClassLoader is alive; not sure whether there's one intern pool per CL or one for the whole JVM, but it's probably irrelevant) and the same string object will be used on every invocation.
If you make it a public static final there would definitely be an improvement, as the concatenation can be done by the compiler instead of at execution time.
If you make it final within the method (i.e. still as a local variable), that may have the same effect - I'm not sure.
"fn" would be interned. Hence the same object would be used again and again.
In worst case you can jsut replace it by :
String METHOD_NAME = "fn".intern();
Though i think its unnecessary.
Making it public static final is good.
To my knowledge, METHOD_NAME -- the reference to String 'fn' will be allocated in every call of fn(). However, the Object of String 'fn' should be allocated once, for it's a String constant and will be put in the String pool.
Replacing it with a public static final might be a good idea, but it's for programming style rather than performance concern.
String literals are placed in the constant pool. There isn't any point in putting the string in a static final - this behavior is guaranteed by the JLS.
(and yes, the string will also be interned, though that isn't especially relevant to your concerns)
would the variable METHOD_NAME get created every time fn() is called?
The variable would be "created" (better "set") but the string not (since it is an internalized string residing in the JVM's string pool). So it's just a new reference to the same string.
would the JVM do some optimization so that the variable METHOD_NAME is not garbage collected and reused the next time fn() is called
The variable METHOD_NAME is just a name for a reference. The referenced string is likely to reside in the string pool.
would there a performance improvement if I made the variable a public static final?
There might be, but I'd rather ignore that since it would be micro-optimization.
Actually, in order to get a small performance improvement, you should think about whether it is necessary to print the log statement every time, especially in a production environment where it might be too verbose.
ya go for public static final, that would increase preformance.
精彩评论