gpt4 book ai didi

Java子字符串内存泄漏

转载 作者:行者123 更新时间:2023-11-30 06:21:44 27 4
gpt4 key购买 nike

基于关于获取 String Java String.split memory leak? 子串的讨论,我一直在分析两个示例子字符串的用法示例。

如果调用者在对象中存储字段的子字符串,则对象不会被垃圾回收。当我运行我得到的代码和 OutofMemory 异常,并在通过 VisualVM 监视它时看到 char[] 分配大小的增加

public class TestGC {
private String largeString = new String(new byte[100000]);
String getString() {
return this.largeString.substring(0,2);
//return new String(this.largeString.substring(0,2));
}

public static void main(String[] args) {
java.util.ArrayList<String> list = new java.util.ArrayList<String>();
for (int i = 0; i < 100000; i++) {
TestGC gc = new TestGC();
list.add(gc.getString());
}
}
}

使用以下代码,我没有收到错误,在通过 VisualVM 分析内存使用情况后,我意识到分配的 char[] 大小在某个时候增加然后以某种方式减少,然后再次增加并在某个时候减少(GC 工作它的工作)。它会永远持续下去。

public class TestGC {
private String largeString = new String(new byte[100000]);

String getString() {
//return this.largeString.substring(0,2);
return new String(this.largeString.substring(0,2));
}

public static void main(String[] args) {
java.util.ArrayList<String> list = new java.util.ArrayList<String>();
for (int i = 0; i < 100000; i++) {
TestGC gc = new TestGC();
list.add(gc.getString());
}
}
}

我真的很想了解在第二个示例中 GC 收集然后从堆内存中删除的内容?为什么在第一个示例中 GC 无法回收相同的对象?

在第一个示例中 largeString.substring(0,2)); 发送一个引用,在第二个示例中 new String(this.largeString.substring(0,2)); 创建新对象。这两种情况对 GC 的行为应该没有问题?

最佳答案

在第一个示例中,每次围绕循环创建新的 TestGC 对象时,您也会创建一个从 100000 字节数组初始化的新字符串。当您调用 String.substring 时,您将返回相同的大长字符串,但偏移量设置为 0,计数设置为 2。因此所有数据仍在内存中,但是当您使用 String 时,您只会看到中指定的 2 个字符子字符串调用。

在第二个例子中,你在每次循环中再次创建新的字符串,但是通过调用 new String(String.substring) 你丢弃了字符串的其余部分,只在内存中保留了 2 个字符,所以剩下的可以被垃圾收集。

正如评论中的链接所说,此行为在 1.7.0_06 中已更改,因此 String.substring 返回的字符串将不再共享相同的 char[]。

关于Java子字符串内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20081659/

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