gpt4 book ai didi

java - java中substring方法的内存泄漏

转载 作者:行者123 更新时间:2023-12-01 07:24:59 28 4
gpt4 key购买 nike

我正在搜索由java中的subString()方法引起的内存泄漏。我在互联网上阅读了一些文章并获得了一些知识,但最终我感到有点困惑。一篇文章提到“String类中的substring方法,调用String(int offset, int count, char value[])构造函数来创建新的String对象。这里有趣的是,value[],它与用于代表原始字符串”。这对我来说很清楚。

它还提到“如果原始字符串很长,并且有大小为 1GB 的数组,无论子字符串有多小,它都会容纳 1GB 数组。这也会阻止原始字符串被垃圾收集,万一没有任何实时引用”。

文章链接位于此处 { http://javarevisited.blogspot.sg/2011/10/how-substring-in-java-works.html }

我无法理解这一点。请有人解释一下,如果原始字符串没有任何实时引用,它如何阻止垃圾收集?

根据我的一点了解,在java中,任何没有直接或间接引用的对象都有资格被垃圾收集器收集。如果 subString 方法使用与表示原始字符串相同的字符数组,原始字符串如何保留而不被垃圾收集?

同样,我想知道内存泄漏是否是由于使用相同的字符数组来表示原始字符串而引起的,因为新字符串 {String returned by subString method} 与原始字符串相比会非常少,或者因为原始字符串字符串仍然保留而没有被垃圾收集?

请有人帮我澄清一下

最佳答案

当您在 Java 中分配任何内容(在本例中为 String)时,只要您仍然有访问它的方式,它就会保留在内存中。如果你写

String s = "blah";

那么 s 是对该 String引用。只要至少有一个对 String 的引用,JVM 就知道它需要保留在内存中。一旦不再有引用,JVM 就可以清理它并在需要时回收内存。

如果你写

String s = "myverylongstring...somemore...someotherstuff";

那么你已经用掉了相当多的内存了。在内部,这将表示为一个 char[],其中包含 String 的所有字符,边缘有一些额外的 gubbin,以便您可以使用 字符串 API。

现在,如果你这样写会发生什么

s = s.substring(20,30);

这样 s 现在只是对原始 String 的一部分的引用? JVM 可以通过两种方式处理它。一种是将整个 char[] 保留在内存中,但只需更改它准备让您访问的 char[] 的哪一位。另一种是将 char[] 的相关位复制到新数组中,然后删除对旧数组的所有引用。

第一种方法很快,因为它不需要任何复制。但是,如果您现在只想要巨大 String 的一小部分,那么整个大 String 永远无法完全清理,因为它的整个 >char[] 仍在内存中被使用。事实上,只有部分被使用意味着它的没有内存可以被回收。

第二种方法速度较慢,因为它需要复制操作。但这确实意味着之前的 String 可以被完全清理,因为旧的 char[] 不再被使用。

Java曾经遵循第一种方法,但最近(Java 7 及以上)它改用第二种方法。因此,内存泄漏曾经是 substring() 调用的一个问题,但现在已不再是问题了。

关于java - java中substring方法的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26572218/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com