我有一个应用程序,它使用大量内存差异来处理两个可能很大(100k +)目录的内容。对我来说这样的操作会占用大量内存是有意义的,但是一旦我的差异操作完成,堆就会保持相同的大小。
我基本上有代码实例化一个类来存储源和目标上每个文件的文件名,文件大小,路径和修改日期。我保存了其他数组中的添加,删除和更新。然后我clear()
我的源和目标数组(现在可能是100k +),留下相对较少的添加,删除和更新数组。
在我clear()
我的目标和源数组之后,内存使用情况(通过VirtualVM和Windows任务管理器可见)不会丢失。我没有足够的经验来使用VirtualVM(或任何分析器)来弄清楚占用所有这些内存的内容。 VirtualVM的堆转储列出了保留大小为几兆字节的前几个对象。
有什么能帮助我指明正确的方向吗?
答案 0 :(得分:2)
如果使用的堆在垃圾收集后关闭,那么它可能会按预期工作。当Java需要更多内存时会增加它的堆,但不会释放它 - 它更喜欢保留它以防应用程序再次使用更多内存。有关此主题的信息,请参阅Is there a way to lower Java heap when not in use?,了解在使用的堆量减少后堆未被减少的原因。
答案 1 :(得分:2)
VM根据命令行参数-XX:MinHeapFreeRatio
和-XX:MaxHeapFreeRatio
增大或缩小堆。当可用百分比达到-XX:MaxHeapFreeRatio
时,它会缩小堆,默认值为70。
在Oracle's bug #6498735中对此进行了简短的讨论。
答案 2 :(得分:1)
根据您的代码,您可能会产生内存泄漏,垃圾收集器无法释放它们。
我建议您检测代码以发现潜在的内存泄漏。一旦排除或修复,我将开始查看代码本身以获得可能的改进。
请注意,例如,如果您使用try / catch / finally块。可能根本不会调用finally块(或者至少不立即调用)。如果你在finally块中执行一些资源释放,这可能就是答案。
尽管如此,请阅读此主题,例如:http://www.toptal.com/java/hunting-memory-leaks-in-java