如何缩小Java堆空间?

9

我有一个使用DOM处理大型XML文件的Java控制台应用程序。基本上,它从数据库中获取数据创建XML文件。 现在,正如你所猜测的那样,它使用了大量的内存,但令我惊讶的是,这与糟糕的代码无关,而与“java堆空间不收缩”有关。 我尝试使用以下JVM参数从Eclipse运行我的应用程序:

-Xmx700m -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20

我甚至添加了

-XX:-UseSerialGC

我发现并行GC忽略“MinHeap”和“MaxHeap”选项。即使使用了所有这些选项,我的应用程序内存使用情况的图形如下所示: java app graph 您可以看到,在某一点上,我的应用程序占用了大约400MB的堆空间,堆增长到了大约650MB,但几秒钟后(当XML生成完成时),我的应用程序的已用堆降至12MB,但“堆大小”仍然保持在大约650MB。它占用了我650MB的内存!这很奇怪,不是吗?
**有没有办法强制JVS将可用堆大小缩小到当前已用堆的150%?**比如,如果我的应用程序需要15MB的内存,则堆大小为20MB;当我的应用程序请求400MB的内存时,堆增长到600MB,重型操作完成后,堆大小立即降至20MB?

1
@PeterBratton,你可能重复的问题的被接受答案是错误的。 - Marko Topolnik
3
@Marko 没关系,这是完全相同的问题。 - Peter Bratton
1
@PeterBratton 这很重要。你不仅向 OP 发送了一条信息,还向其他所有人发送了这个问题的答案与另一个问题的答案是相同的信息。 - Marko Topolnik
2
@Marko 如果你有更好的答案,请发表出来,我很乐意为你投票。但是我认为,在这个网站上,让两个地方回答相同的问题不符合社区的利益。如果重复的问题是错误的,你应该在那里解释原因。无论如何,根据我理解的stack exchange的原则,这是一个重复的问题。 - Peter Bratton
1
@MarkoTopolnik 为什么你和Peter不把这个问题带到元站讨论一下呢?假设目前还没有关于重复问题和错误接受答案的提问(我目前找不到这样的问题),这将会是一个很好的讨论,我们都可以得到一些明确的解释。坦率地说,我认为你们两个都有合理的观点。 - Paul Richter
显示剩余7条评论
1个回答

2
您应该使用Parallel collection并使用-XX:-UseAdaptiveSizePolicy。文档适用于Java 1.5,但我找不到更多更新的内容。
块引用: -XX:+ UseParallelGC垃圾收集器默认使用的-XX:+ UseAdaptiveSizePolicy实现已更改为考虑三个目标: 1.所需的最大GC暂停目标 2.所需的应用程序吞吐量目标 3.最小占用空间
实施检查(按此顺序): 1.如果GC暂停时间大于暂停时间目标,则减小世代大小以更好地实现目标。 2.如果达到了暂停时间目标,则考虑应用程序的吞吐量目标。如果未达到应用程序吞吐量目标,则增加世代的大小以更好地实现目标。 3.如果同时达到了暂停时间目标和吞吐量目标,则减小世代的大小以减少占用空间。

1
是的!这解决了问题!使用"-XX:-UseAdaptiveSizePolicy" 和 "-XX:+UseParallelGC" 似乎解决了问题 :) 非常感谢! - guest86
自Java 1.4起,“UseParallelGC”应该是默认设置。 - Marko Topolnik
抱歉,我使用了“-XX:-UseParallelGC”(注意“ - ”)。使用“+”时,堆空间会慢慢增长(与应用程序一起),并且会减缓应用程序的速度;而使用“-”时,它的增长方式与通常相同,但最终会缩小。 ;) - guest86
我会小心处理那些设置,因为它们可能会影响你的性能。你确定你不是出于某种抽象的“正确”感而这样做吗? - Marko Topolnik
他们并不完全“建议”关闭它;他们只是建议,如果手动调整,则应将其关闭。顺便说一句,那看起来像是一个非常老的演示文稿:他们仍然谈论-d32和串行收集器作为默认设置。 - Marko Topolnik
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接