1

Java中是否有任何机制可以在读取大型文本文件时减少内存使用?

几乎我遇到的每个程序都使用 String 来读取文本文件。但是 Java 为每个 String 文字保留空间。这就是为什么我认为内存使用量会增加,因为所有 String 对象都被存储了。java.io 的所有类都处理字符串。但是如果我们不使用 StringBuilder 那么我们如何减少内存使用呢?

毕竟减少内存使用是 StringBuilder 的主要关注点[因为它不像 String 那样不可变]。那么我们如何在不使用 String 的情况下在 Java I/O 操作中利用它的特性,即不使用类似这样的东西: sb.append([String object]);

4

6 回答 6

1

假设您有n字符串,您从输入中读取每个长度为 1 的字符串 - 为简单起见。

在阅读时使用operator+on strigns 将在String每次连接字符串时创建一个对象,因此您得到长度为 1,2,3,...,n 的字符串

因此,组合字符串的总内存使用量不包括您从输入1 + 2 + .. + n = O(n^2)中读取的字符串n

而如果您使用StringBuilder创建最终字符串,您实际上创建n- 用于输入 [每个长度为 1] 和一个对象用于最终字符串 - 大小n,因此总内存使用量为1 + 1 + .. + 1 + n = O(n)

因此,即使您使用sb.append(String)- 空间使用情况也比创建所有中间字符串要好 - 因为您不需要创建中间字符串对象。

此外 - 使用时性能 [时间] 应该更好StringBuilder- 既因为您创建的对象更少,也因为更少的内存使用量 - gc 不需要像天真地连接字符串时那样努力工作。

(*)请注意,很容易看出上面仍然适用于任何长度的字符串。

于 2012-03-24T17:38:21.923 回答
0

您可以使用 StringBuilders 的 append char 方法,以避免创建中间字符串,请查看此帖子:https ://stackoverflow.com/a/9849624/102483请记住,没有办法减少内存占用final 字符串,使其小于您正在阅读的文件的大小。

于 2012-03-24T17:34:10.267 回答
0

根据您正在执行的操作,您可以创建一个 String 和/或 StringBuilder 对象池,这些对象加载了您需要的值、清除然后重用。您可以将池配置为增长到最大值,如果池中的对象未使用,则将它们设置为 null,最终它们将被垃圾收集器回收。

于 2012-03-24T17:35:55.280 回答
0

您可能需要考虑这样的事情:

  BufferedReader reader = 
    new BufferedReader(
      new InputStreamReader(
        new ByteArrayInputStream(data)));
  String line;

  while ((line = reader.readLine()) != null)
    ...

有关更多详细信息,请参阅这些链接:

大ByteBuffer的BufferedReader?

http://www.tutorialspoint.com/java/java_bytearrayinputstream.htm

于 2012-03-24T17:40:09.407 回答
0

Reader及其子类基于 char 和 char[],只有便捷方法使用 String。由于 StringBuilder.append() 接受 char[],如果只使用围绕 char[] 构建的方法,则可以避免创建不必要的 String 对象。

请注意,虽然这减少了临时创建的 String 对象的数量,但总体内存需求保持不变,但 gc 将收集任何其他创建的 String。

于 2012-03-24T17:57:51.647 回答
0

而不是字符串,尝试使用StringBuilder附加从文件中读取的数据。如果您使用String,您最终可能会在内存中创建多个字符串对象。

于 2012-03-24T18:09:38.620 回答