我正在使用Java制作一个保存和加载文件的应用程序,所以我使用流。我从一个文件中获得一个流,然后用这个流在另一个文件夹中创建一个新文件。问题是,在使用流并关闭它之后,本应释放的内存仍然存在。
例如,我加载了一个100mb的文件(任务管理器显示java.exe增加了100mb),然后我将文件保存在另一个文件夹中,并用stream.close()关闭流。但java.exe并没有减少100mb。当我多次保存和加载文件,并且java.exe超过600mb时,它就会减少到300mb。每当它即将超过600亿时,它就会减少到300亿。为什么会这样?为什么调用stream.close()时内存不能达到0mb?为什么它在大约600mb的时候会释放内存,却没有释放所有内存?
这就是我如何从字符串路径加载流,然后关闭流:
String path = ... //File path
InputStream stream = new BufferedInputStream(new FileInputStream(path));
stream.close();
谢谢你的回复。
BufferedInputStream默认使用8 KB的固定大小,因此它不会泄漏超过8 KB(外加一点开销)
我加载了一个100mb的文件(任务管理器显示java.exe增加了100mb),
这意味着您正在使用100MB的对象来处理文件。
但是java.exe并没有减少100mb
没有理由。它很可能会在GC之后发生,但除非你需要,否则你不想这样做,我怀疑你不想。
每当它即将超过600亿时,它就会减少到300亿。为什么会这样?
您触发了一个垃圾收集。很可能是一个小集合。
当我调用stream.close()时,为什么内存不能达到0mb?
它启动时不是0 MB,GC时会收回内存,但你不想做不必要的事情。
为什么它在600mb左右时会释放内存,而不会释放所有内存?
它有多个内存区域,它试图做最简单的工作,通常是清理eden空间。
您看到的是Java内存系统的正常运行,分配的内存不一定会返回给操作系统。
您不应该在操作系统级别检查java.exe的内存,而应该使用内存分析器,如内置的JConsole工具(或免费的EclipseMAT进行更深入的分析)。
在您的代码中,FileInputStream是匿名实例。
由于文件较大,可能会存储在虚拟内存/虚拟内存中。在java启动垃圾收集之前,它不会关闭。
将FileInputStream创建为新的命名实例并关闭
它应该工作