减少Java堆大小

减少Java堆大小,java,memory,profiling,heap-memory,Java,Memory,Profiling,Heap Memory,我有一个应用程序,它使用大量内存来区分两个潜在的巨大(100k+)目录的内容。对我来说,这样一个操作会占用大量内存是有道理的,但一旦我的差异化操作完成,堆的大小就保持不变 我基本上有代码实例化一个类来存储源和目标上每个文件的文件名、文件大小、路径和修改日期。我将添加、删除和更新保存在其他阵列中。然后我clear()我的源数组和目标数组(现在可能每个都有100k以上),只剩下相对较小的添加、删除和更新数组 在我清除目标和源阵列之后,内存使用率(通过VirtualVM和Windows任务管理器可见)

我有一个应用程序,它使用大量内存来区分两个潜在的巨大(100k+)目录的内容。对我来说,这样一个操作会占用大量内存是有道理的,但一旦我的差异化操作完成,堆的大小就保持不变

我基本上有代码实例化一个类来存储源和目标上每个文件的文件名、文件大小、路径和修改日期。我将添加、删除和更新保存在其他阵列中。然后我
clear()
我的源数组和目标数组(现在可能每个都有100k以上),只剩下相对较小的添加、删除和更新数组

在我清除目标和源阵列之后,内存使用率(通过VirtualVM和Windows任务管理器可见)不会下降。我对VirtualVM(或任何剖析器)的经验不足,无法弄清楚是什么占用了所有这些内存。VirtualVM的堆转储列出了保留大小为几兆字节的前几个对象


有什么可以帮我指出正确的方向吗?

根据您的代码,您可能会产生内存泄漏,而垃圾收集器无法释放它们

我建议您插入代码,以发现潜在的内存泄漏。一旦排除或修复了这个问题,我将开始查看代码本身,以寻求可能的改进

请注意,例如,如果使用try/catch/finally块。可能根本不会调用finally块(或者至少不会立即调用)。如果在finally块中释放一些资源,这可能就是答案


不过,请仔细阅读这个主题,例如:如果使用的堆在垃圾收集后下降,那么它可能会按照预期工作。Java在需要更多内存时会增加堆,但不会释放内存——它更愿意保留堆,以防应用程序再次使用更多内存。有关使用的堆数量减少后堆为何不减少的主题,请参阅。

虚拟机根据命令行参数
-XX:MinHeapFreeRatio
-XX:MaxHeapFreeRatio
增大或缩小堆。当空闲百分比达到
-XX:MaxHeapFreeRatio
时,它将收缩堆,其默认值为70


在中有一个简短的讨论。

查看内存使用情况时,您确定垃圾收集器已经运行了吗?内存使用率只会在(可能是主要的)GC运行后下降。根据virtualvm,堆保持不变,而使用的堆将下降(大约到我预期的水平,远远低于总堆的一半)。堆大小大致与windows任务管理器告诉我java正在使用的内容一致。我在分析应用程序时看到了通常的GC楼梯收集模式,我只是不知道为什么总堆仍然如此之大。我只是浏览了一下该线程,它已经提供了大量信息。非常感谢。