在我正在维护的项目中,我发现了一个java类,其方法“fn”类似于下面所示的方法
class Test{
public void fn(){
String METHOD_NAME = "fn";
...
sysout("In " + METHOD_NAME);
}
}
程序无限期运行,方法'fn'被称为连续且频率非常高。问题是
(我猜字符串池在这里扮演一些角色)
谢谢, Kiran Mohan
答案 0 :(得分:6)
是的,每次输入方法时都会创建变量 METHOD_NAME
,但这是一个非常非常便宜的操作(实际上创建2个变量与创建1一样昂贵)
值(即String
对象)"fn"
将不重新创建,但将来自常量字符串池。
但是,表达式"In " + METHOD_NAME
将被重新计算,并且每次都会创建一个新的String
对象,因为它不是compile time constant expression。< / p>
如果METHOD_NAME
在static final
,那么该表达式也将是一个编译时常量,因此将来自常量池。
答案 1 :(得分:3)
变量不是垃圾收集 - 对象是。
“fn”是一个字符串文字,因此它将被实习。它不会被垃圾收集(至少在ClassLoader存活的时候;不确定每个CL是否有一个实习池或整个JVM有一个,但它可能不相关)并且每个调用都会使用相同的字符串对象。 / p>
如果你把它作为公共静态决赛,那么肯定是一种改进,因为连接可以由编译器而不是在执行时完成。
如果你在方法中最终(即仍作为局部变量),可能具有相同的效果 - 我不确定。
答案 2 :(得分:2)
“fn”将被实习。因此,将一次又一次地使用相同的对象。
在最坏的情况下,您可以通过以下方式替换它:
String METHOD_NAME = "fn".intern();
虽然我认为这是不必要的。
将其公开为静态决赛是好的。
答案 3 :(得分:1)
据我所知,METHOD_NAME - 对字符串'fn'的引用将在每次调用fn()时分配。但是,字符串'fn'的对象应该被分配一次,因为它是一个String常量,并且将放在String池中。
用公共静态决赛替换它可能是一个好主意,但这是编程风格而不是性能问题。
答案 4 :(得分:0)
字符串文字放在常量池中。将字符串放在静态final中没有任何意义 - 这种行为是由JLS保证的。
(是的,该字符串也将被实习,但这与您的担忧并不特别相关)
答案 5 :(得分:0)
每次调用fn()时都会创建变量METHOD_NAME吗?
变量将被“创建”(更好地“设置”)但字符串不是(因为它是驻留在JVM的字符串池中的内化字符串)。所以它只是对同一个字符串的新引用。
JVM会进行一些优化,以便变量METHOD_NAME不会被垃圾收集并在下次调用fn()时重用
变量METHOD_NAME只是参考的名称。引用的字符串可能驻留在字符串池中。
如果我将变量设为公共静态最终版,会不会有性能提升?
可能有,但我宁愿忽略它,因为它将是微优化。
实际上,为了获得较小的性能提升,您应该考虑是否每次都需要打印日志语句,尤其是在可能过于冗长的生产环境中。
答案 6 :(得分:-2)
你去公共静态决赛,这将提高性能。