String samplel = "ToBeGarbageCollected";
String sample2 = samplel.substring(0, 1);
samplel = null;
我知道子字符串在内部会保留对原始字符串的引用。
但是通过将 sampell
显式定义为 null
,sample1 和 sample2 是否可用于垃圾收集?
我记得在某处看到,如果父对象被显式设置为 null
,则所有子值都可用于垃圾回收。这对上述情况有好处吗?
我只是好奇这是否是亲子关系场景?如果不是,这会导致 sample1
或 sample2
可用于垃圾回收吗?
String samplel = "ToBeGarbageCollected";
String sample2 = new String(samplel .substring(0, 1));
samplel = null;
最佳答案
首先要说的是,垃圾回收不会立即发生。因此,将 null
分配给任何内容都不会/不能导致垃圾回收。 可能 做的是使对象变得无法访问 ... 这将使它成为 future GC 运行中垃圾收集的潜在候选对象。
现在来看你的具体例子。
重要说明:以下内容仅适用于较旧的 JVM;即 Java 7 update 5 及更早版本。在 Java 7 更新 6 中,他们更改了 String.substring()
以便目标字符串和生成的子字符串不共享支持数组。这消除了 substring
的潜在存储泄漏问题。
substring
方法不会在新字符串中放置对原始字符串的引用。它实际上做的是保存对原始字符串支持数组的引用;即保存字符的数组。
不过话虽如此,将null
赋值给sampell
并不足以让整个原始字符串的状态不可达。原始字符串的整个 后备数组将保持可访问性...这意味着它不会成为垃圾收集的候选对象。
但是还有一个问题。您将 sample1
设置为字符串文字,表示字符串文字的字符串对象始终可访问(除非整个类都被卸载!)
But by explicitly defining samplel as null, will sample1 and sample2 be available for garbage Collection?
原始的 sample1
对象将保持完全可访问,并且 sample2
将保持可访问,除非该变量超出范围。
如果 sample1
不是文字并且没有其他引用,那么答案就会不同。 sample1
对象将无法访问,但它的支持数组仍可通过 sample2
访问。
在您的第二个示例中,复制子字符串会导致创建一个新的字符串。并且保证新字符串不会与原始字符串和临时子字符串共享支持数组。在这种情况下,分配 null
是不必要的。
Will now both sample1 and sample2 be available for garbage Collection?
对于 sample1
是文字的情况,答案与上述相同。
如果 sample1
不是文字并且没有其他引用,那么 sample1
和临时子字符串现在将无法访问。
I just want to know where does String constructor be helpful.
理论上是这样。
在实践中,这取决于当 GC 最终开始查找时引用是否仍然可以访问......以及所讨论的字符串是否足够大和数量足以对内存使用产生重大影响。
在实践中,通常不满足该先决条件,通常创建一个像这样的新字符串也无济于事。
关于java - 另一个字符串的子字符串会阻止父字符串被垃圾收集吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15857883/