gpt4 book ai didi

java - 使用 append 时,StringBuilder 使用更多内存

转载 作者:搜寻专家 更新时间:2023-10-31 19:56:03 24 4
gpt4 key购买 nike

{
StringBuilder fileBuff = new StringBuilder();
long before = getUsedMem();
try {
//Open InputStreamReader here
while ((currLine = lnr.readLine()) != null) {
fileBuff.append("\r\n" + currLine);
}
//Close streams
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("usedTotal: " + (getUsedMem() - before));
}

private long getUsedMem() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}

多次运行代码时,我得到 usedTotal ~ 14279888,但如果我用 fileBuff.append("\r\n") 替换。 append(currLine) 我得到了几乎两倍的内存 ~33264440
有人可以解释一下原因吗,据我所知,String 连接也使用 StringBuilder

我:fileBuff.append("\r\n"+ currLine);

      62: aload         6
64: invokevirtual #16 // Method java/io/LineNumberReader.readLine:()Ljava/lang/String;
67: dup
68: astore_2
69: ifnull 99
72: aload_1
73: new #2 // class java/lang/StringBuilder
76: dup
77: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
80: ldc #17 // String \r\n
82: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
85: aload_2
86: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
89: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
92: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
95: pop
96: goto 62

II fileBuff.append("\r\n").append(currLine)

      62: aload         6
64: invokevirtual #16 // Method java/io/LineNumberReader.readLine:()Ljava/lang/String;
67: dup
68: astore_2
69: ifnull 86
72: aload_1
73: ldc #17 // String \r\n
75: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
78: aload_2
79: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
82: pop
83: goto 62

显然#II 应该使用更少的内存,但事实并非如此。我正在阅读的文件有 50k 长。

最佳答案

当使用 StringBuilder 时,您将保留空间以将字符串添加到您的缓冲区。这是一个使用 StringBuilder 而不是字符串的好例子,因为您使用的是 while 循环。

当您使用 String 时,每次键入如下内容时:

String s = s + someOtherString;

您正在丢弃现有的 s 字符串并创建一个新字符串来代替它,即 s + someOtherString。这意味着您不断需要新的内存来制作连接的字符串,丢弃旧的,并将变量的引用放入新的字符串。

使用 StringBuilder,您可以附加到您的字符串,而无需删除现有部分。

所以是的,它使用更多内存,但与仅使用字符串相比,它在某些情况下非常有效。

换句话说:String 是一个 immutable objectStringBuilder 则不是。


在您的代码中:

fileBuff.append("\r\n" + currLine);

这与 new String("\r\n"+ currLine); 相同,都是 1 个 String 对象

您正在使用 1 个追加。

在你的评论中你说如果你使用这个:

fileBuff.append("\r\n").append(currLine);

这与 new String("\r\n");new String(currLine); 相同,它们都是 2 个 String 对象

您几乎获得了两倍的内存。这是有道理的,因为您正在进行 2 倍追加,因此使用了双倍的内存。

关于java - 使用 append 时,StringBuilder 使用更多内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17487373/

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