小编典典
注意:此答案使用的示例可能与现代运行时JVM库无关。 特别是,该substring示例在OpenJDK / Oracle 7+中不再是问题。
我知道这与人们经常告诉您的内容背道而驰,但是有时显式创建新String实例 可能 是减少内存的重要方法。
由于字符串是不可变的,因此有几种方法可以利用该事实并共享支持字符的数组以节省内存。但是,有时这可以通过防止垃圾回收那些数组未使用的部分来实际上增加内存。
例如,假设您正在解析日志文件的消息ID,以提取警告ID。您的代码如下所示:
//Format:
//ID: [WARNING|ERROR|DEBUG] Message...
String testLine = "5AB729: WARNING Some really really really long message";
Matcher matcher = Pattern.compile("([A-Z0-9]*): WARNING.*").matcher(testLine);
if ( matcher.matches() ) {
String id = matcher.group(1);
//...do something with id...
}
但是看看实际存储的数据:
//...
String id = matcher.group(1);
Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
char[] data = ((char[])valueField.get(id));
System.out.println("Actual data stored for string \"" + id + "\": " + Arrays.toString(data) );
这就是整个测试行,因为匹配器只是在相同的字符数据周围包装了一个新的String实例。当您更换比较结果String id =
matcher.group(1);用String id = new String(matcher.group(1));。
2020-12-03