Java FileReader内存使用模式

时间:2017-09-15 17:09:01

标签: java memory filereader

似乎FileReader正在将文件读入内存但我不想要它。根据操作系统报告的java内存使用情况,我的简单程序从最初的~11MB上升到60MB以上,同时读取~50MB的文件。只是为了基线,没有FileReader的以下程序运行大约30秒,并且仍然固定在~11MB内存使用。

public class TestClass {
    public static void main(String[] args) throws Exception {
        int count=0;
        while ((count++) < 30000) {
            Thread.sleep(1);
        }
    }
}

然而,一旦我添加了FileReader,在java进程结束之前,内存使用量将从~11MB增加到超过60MB。但根据文档,&#34; FileReader用于读取字符流。&#34;我错过了什么?

import java.io.FileReader;

public class TestClass {
    public static void main(String[] args) throws Exception {
        FileReader reader = new FileReader("/tmp/big.txt");
        int charCode = -1;
        while ((charCode = reader.read()) > -1) {
            Thread.sleep(1);
        }
        reader.close();
    }
}

2 个答案:

答案 0 :(得分:0)

运行JVM时,此JVM会从底层系统分配虚拟内存。因此,只有在将某些内容写入内存页面时才真正分配内存。这意味着,例如,当您实例化新对象时,实际上会分配内存。因为实例化新对象会将一些数据写入内存。但是当对象被丢弃时,JVM不会告诉操作系统。因此,从操作系统的角度来看,仍然会分配内存。但是,当然,稍后,JVM可以在同一内存位置重新分配新对象,因为JVM知道哪个内存空间是空闲的。但是这绝对不是由许多JVM强制执行的:它们不需要在先前丢弃的对象的同一内存位置分配新对象,因为它们有大量的虚拟内存。

因此,当一次调用reader.read()时,系统库会为临时对象(数据读取)分配一些内存,并在返回之前取消引用这些对象。但是收集这些对象的垃圾收集器并没有告诉操作系统相应的块。

就像没有带有SSD磁盘的TRIM一样:磁盘不知道丢弃和可用的块。

无论如何,有人可能会创建一个具有不同内存使用行为的JVM,因为该行为留给了实现者。

答案 1 :(得分:0)

我的猜测是内存使用量的增加是由于所有文件I / O支持软件的加载,而且内存使用和文件大小的增加都是〜50MB的巧合。您可以通过尝试使用明显不同的文件大小来检查这一点。如果您尝试最小化内存使用量,也可以在调用System.gc();之前尝试调用Thread.sleep(1);。即使你的代码几乎没有垃圾,底层的I / O框架也可能生成垃圾(重新分配缓冲区等)。