4

我正在使用 Java 制作一个保存和加载文件的应用程序,所以我使用的是流。我从一个文件中获取一个流,然后我使用这个流在另一个文件夹中创建一个新文件。问题是,在使用流并关闭它之后,应该释放的内存仍然存在。

例如,我加载了一个 100mb 的文件(任务管理器显示 java.exe 增加了 100mb),然后我将文件保存在另一个文件夹中并使用 stream.close() 关闭流。但是 java.exe 不会减少 100mb。当我多次保存和加载文件时,java.exe 超过 600mb,然后减少到 300mb。每次即将超过 600mb 时,它都会减少到 300mb。为什么是这样?为什么我调用 stream.close() 时内存不能达到 0mb?为什么它在大约 600mb 时释放内存,并且没有释放所有内存?

这就是我从字符串路径加载流然后关闭流的方式:

String path = ... //File path
InputStream stream = new BufferedInputStream(new FileInputStream(path));
stream.close();

感谢您的回复。

4

3 回答 3

4

BufferedInputStream 默认使用 8 KB 的固定大小,因此它不能泄漏超过 8 KB(加上一点开销)

我加载了一个 100mb 的文件(任务管理器显示 java.exe 增加了 100mb),

这意味着您正在使用 100 MB 的对象来处理文件。

但是java.exe不会减少100mb

没有理由应该。它很可能会在 GC 之后发生,但除非您需要而且我怀疑您不需要,否则您不想这样做。

每次即将超过 600mb 时,它都会减少到 300mb。为什么是这样?

您已经触发了垃圾收集。很可能是次要收藏。

为什么我调用 stream.close() 时内存不能达到 0mb?

它开始时不是 0 MB,当你 GC 时你会取回内存,但你不想不必要地这样做。

为什么它在大约 600mb 时释放内存,并且没有释放所有内存?

它有多个内存区域,它试图做最简单的工作,通常是清理伊甸园空间。

于 2012-09-26T16:53:25.790 回答
2

你看到的是Java内存系统的正常运行,分配的内存不一定还给操作系统。

与其在操作系统级别检查 java.exe 的内存,不如使用内存分析器,例如内置的JConsole工具(或免费的Eclipse MAT 进行更深入的分析)。

于 2012-09-26T16:51:59.830 回答
-1

在您的代码中 FileInputStream 是匿名实例。

由于文件较大,可能会存储在 Virtual Memory/Virtual Ram 中。它不会关闭,直到 java 开始垃圾收集。

将 FileInputStream 创建为新的命名实例并关闭

它应该工作

于 2012-09-26T16:53:03.797 回答