我有个问题。我正在阅读有关子字符串的博客。在下面引用它。
这里值得记住的一点是子字符串也是由原始字符串使用的字符数组备份的。如果原始字符串对象非常大而子字符串非常小,这可能会很危险,因为即使是一小部分也可以保存完整数组的引用并防止它被垃圾收集,即使该特定字符串没有其他引用
我不明白说一个小参考可以防止垃圾收集是什么意思。有人可以解释这个概念吗?谢谢
我有个问题。我正在阅读有关子字符串的博客。在下面引用它。
这里值得记住的一点是子字符串也是由原始字符串使用的字符数组备份的。如果原始字符串对象非常大而子字符串非常小,这可能会很危险,因为即使是一小部分也可以保存完整数组的引用并防止它被垃圾收集,即使该特定字符串没有其他引用
我不明白说一个小参考可以防止垃圾收集是什么意思。有人可以解释这个概念吗?谢谢
这意味着作为substring()
操作结果创建的所有新字符串都包含对原始字符串中字符数组的引用,并且原始字符数组不会被垃圾收集,直到从它派生的所有子字符串也被垃圾收集,无论如果它们大或小。
正如评论中所指出的,这种情况在 Java 的最新版本(1.7.0_06 和更高版本)中不会出现。请参阅此链接以获取解释,但简而言之:现在substring()
每次都会创建一个新字符串,因此底层char[]
不再共享。
我相信这个链接回答了你的问题:
// Example 1
String samplel = "ToBeGarbageCollected";
String sample2 = samplel.substring(0, 1);
// Example 2
String samplel = "ToBeGarbageCollected";
String sample2 = new String(samplel.substring(0, 1));
substring 方法不会在新字符串中引用原始字符串。它实际上所做的是保存对原始字符串支持数组的引用;即保存字符的数组。
...原始字符串的整个后备数组将保持可访问性...这意味着它不会成为垃圾收集的候选对象。
但还有另一个并发症。您将 sample1 设置为 String 文字,并且表示 String 文字的 String 对象始终是可访问的(除非整个类被卸载!)
在您的第二个示例中,复制子字符串会导致创建一个新字符串。并且保证新字符串不会与原始字符串和临时子字符串共享后备数组
还:
正如 Sotirios Delimanolis 正确所说:Java 7 或更高版本不再适用: