我们几乎到处都使用串联字符串进行记录
例如:catch (Exception e) {
logger.error("setUserSession()" + e.getMessage());
}
但我们怀疑这些语句是否会因字符串突变而导致内存泄漏。有人建议使用String builder。但是我从像StringBuilder vs String concatenation in toString() in Java这样的讨论中理解的是Java Compiler将使用String builder来转换字符串连接。
为了测试这个,我尝试反编译以下java代码(使用JD-GUI);
logger.error("string1" + "string2");
logger.error("setUserSession()" + e.getMessage());
反编译器生成以下代码;
logger.error("string1string2");
logger.error("setUserSession()" + e.getMessage());
但是我期待第二个语句中的String builder,如;
logger.error(new StringBuilder().append("setUserSession()").append(e.getMessage());
所以我有两个疑问:
答案 0 :(得分:6)
StringBuilder
。我认为你对Java有误解。这些对象是String
,Object
,MyObject
还是其他任何内容都无关紧要。只要对它的所有强引用都超出范围,对象就有资格进行垃圾收集,并在适当的时候回收使用的内存。
在Java中泄漏内存的唯一方法是泄漏资源(例如打开流,创建线程等)或者意外地保留对某些内容的引用(例如将其添加到List并且永远不会从List中删除它)。
答案 1 :(得分:0)
最好在日志语句之前检查是否启用了日志级别,如下所示:
if(logger.isErrorEnabled()) {
//At runtime while executing below statement,Java creates "String1" and "String2"
//String objects in the string pool regardless of the log level
logger.error("string1" + "string2");
}
这可以防止在字符串池中不必要地创建“String1”和“String2”对象,尽管日志记录语句不执行任何操作。(如果日志级别比ERROR更大)