首先要说的是,垃圾回收不会立即发生。因此,分配
null任何东西不会/不会 导致 垃圾回收。什么是 可以 做的是使一个对象变得 不可达
…这将使其在未来的GC运行垃圾收集的潜在候选。
现在到您的具体示例。
重要说明: 以下内容 仅 适用于较早的JVM;即Java 7 update 5和更早版本。在Java
7更新6中,它们进行了更改
String.substring(),以使目标字符串和结果子字符串不共享后备数组。这消除了潜在的存储泄漏问题
substring。
该
substring方法不会在新String中放置对原始String的引用。它实际上所做的是保存对原始String的后备数组的引用。即包含字符的数组。
不过话说回来,分配
null到
samplel不足以使整个原始字符串的状态无法访问。原始String的 整个
支持数组将保持可访问的状态…这意味着它将不适合进行垃圾回收。
但是还有另一个复杂之处。您设置
sample1为String文字,并且表示String文字的String对象 始终 可访问(除非整个类都被卸载!)
但是通过将samplel显式定义为null,sample1和sample2是否可用于垃圾回收?
原始
sample1对象将保持完全可访问,并且
sample2除非该变量超出范围,否则将保持可访问。
如果
sample1不是文字,并且没有其他引用,那么答案将有所不同。该
sample1对象将不可访问,但其后备数组仍可通过访问
sample2。
在第二个示例中,复制子字符串会导致创建新的String。并且可以确保新的String不会与原始String和临时子字符串共享后备数组。在这种情况下,分配
null是不必要的。
现在,sample1和sample2都可用于垃圾回收吗?
对于
sample1文字的情况,答案与上述相同。
如果
sample1不是文字,并且没有其他引用,那么
sample1临时子字符串现在将无法访问。
我只想知道String构造函数在哪里有帮助。
从理论上讲将会如此。
在实践中,这取决于GC最终查找时引用是否仍可访问……以及所讨论的字符串是否足够大且足够多,从而对内存使用量产生重大影响。
并且在实践中, 通常 不满足该前提条件,并且创建这样的新鲜String 通常 无济于事。



