【问题标题】:Memory concern for dealing with large String处理大字符串的内存问题
【发布时间】:2017-01-07 08:19:55
【问题描述】:

在我的应用程序中,我编写了一个 REST 调用,仅供开发人员和支持人员使用,它从日志文件加载 n 大小的数据并将其作为文本/纯文本返回,其中 n 是一个可配置的数字,不能超过固定大小。

    RandomAccessFile file = new RandomAccessFile(logFinalPath, "r");
    //chunk default is 100000 max is 500000
    chunk = chunk <=0l?100000:(chunk>500000?500000:chunk);
    long fileSize = file.length();
    //start position is either chunk size from the end or when the file is smaller then from the beginning of file
    long pos = fileSize>chunk?file.length()-chunk:0;    
    int maxSize = (int) (fileSize>chunk?chunk:fileSize);
    file.seek(pos);
    byte[] bytes = new byte[maxSize];
    file.read(bytes);
    file.close();
    logger.info("fileSize : "+fileSize);
    return new String(bytes);

现在这是我的问题,我们知道 String 是不可变的,并且创建的任何新 String 都会进入 String 池,在 JVM 启动并运行之前永远不会被清理。因此,在这种情况下,每次进行此 REST 调用时,它不会对内存造成影响,因为它会不断将大文本加载到字符串池中?

如果是,有什么替代方案,我不能传递字节数组,因为那将是不可读的。怎样才能更好?

更新:请注意,这个问题不是关于字符串的新构造函数或文字表示,而是关于如何优化它以避免将大字符串存储到字符串池中,无论是否有来自堆对象的引用。

【问题讨论】:

标签: java string memory memory-management jvm


【解决方案1】:

我们知道字符串是不可变的

是的。

并且创建的任何新字符串都会进入字符串池

不,除非你打电话给String.intern()

在 JVM 启动并运行之前永远不会被清理。

字符串文字可以从 Java 6 中清除,因为字符串文字被移到了堆中。

那么在这种情况下,每次进行此 REST 调用时,它会不会对内存造成影响,因为它会不断将大文本加载到字符串池中?

大型对象被添加到永久空间中,要清理这些对象,您需要一个您通常希望避免的主要集合。

对性能的影响很小,但不如将byte[] 转换为字符串之后再将其转换回字节那么大。通过将缓存数据保存为byte[]

,您可以节省大量工作(和内存)

我很想在启动时内存映射您的源文件(无论文件有多大,这几乎不使用堆)并根据需要从源文件目录复制到请求的输出,并避免占用尽可能堆复制。

【讨论】:

  • 感谢彼得的回复,我知道我的“假设”,即所有字符串都进入字符串池是没有根据和错误的,最终那些大字符串会被收集。我无法缓存 byte[],因为日志文件不断写入,我想说最后 100 行。内存映射是我只听说过的概念,不确定是否适用于滚动文件,我的意思是日志文件每天都会滚动为新文件,或者说一旦它变成 200MB 大。
  • @RahulKumar 我们使用内存映射来滚动文件,但我们控制生产者和消费者。如果你不是生产者,内存映射会很棘手。
  • 字符串文字可以从 Java 6 中清除,因为字符串文字已移至堆”这句话具有误导性。字符串总是像任何其他对象一样受到垃圾收集。 “永久代”的问题在于它有一个固定的大小,而不是它从未被 GC 处理过。这尤其具有误导性,因为问题与文字无关,并且在字符串对象上调用 intern() 会将其添加到池中,但不会将其转换为文字。由于此类手动添加的池字符串与类无关,因此它们总是可以被垃圾收集(在每个 Java 版本中)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2018-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
相关资源
最近更新 更多