JVM垃圾回收太不频繁 - Clojure

5
我正在开发一个clojure应用程序,但它似乎使用的内存比它应该用的多得多。我以为是内存泄漏问题,但在使用jvisualvm检查后发现,GC并没有经常运行。在红色轮廓处,我手动调用了GC。为什么它分配了300mb,而实际使用只有约30mb?

@HotLicks 给出一个答案,我会接受的。 - Ilia Choly
1
垃圾回收是一个庞大的主题。请参见http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html。 - noahlz
这是一个关于垃圾回收的一般性问题,与Clojure无关。请参见http://stackoverflow.com/questions/3824215/when-is-garbage-collector-used-in-java。已被踩。 - noahlz
@noahz 我怎么知道呢? - Ilia Choly
我来重新表述一下。我在编写Clojure代码时遇到了这个问题。尽管现在看来很显然,但我甚至没有想到它可能是JVM的固有属性。我在发帖之前进行了搜索,只是没有搜索正确的内容。 - Ilia Choly
显示剩余3条评论
3个回答

5

如果你觉得堆太大,可以将其缩小。只有在必要时才会运行GC。

(这些控件随着时间的推移而发生了变化,但我认为它们仍然是以初始堆大小、增量大小和最大大小为单位。如果你的初始堆大小很小,只要没有推动它更高的堆使用的“高水位标记”,它就会保持小。)


5
JVM有调节内存管理的参数,包括初始分配量和最大可分配量。除了这些参数外,JVM无法知道您认为合理的内存使用量。据我所知,没有要求JVM按特定时间表运行垃圾回收,也没有将目标内存使用量作为Java定义的一部分。
假设您已经设置了JVM的最大内存为100MB,目前正在使用50MB(包括死对象)。您有一个需要1MB内存的NEW操作。此时,JVM是否应运行GC?不是必须的:在达到最大值之前,您有足够的空间。但这是个好主意吗?这很难说。哪个更糟,使用大量内存还是频繁运行GC?
作为Java程序员,您通常不应该知道或关心这些事情。只要在声明内存耗尽之前运行GC,有什么区别呢?如果您的应用程序使用了太多的内存,以至于其他应用程序无法分配它们所需的内存,请更改运行时参数以减少最大可用内存。那就是问题的极限。

4
JVM使用分代垃圾收集器。如果通常情况下您有大约30MB的内容处于活动状态,那么您应该将新生代大小设置为60MB左右。这样,垃圾收集器应该会在这些内容被提升到老年代之前从上一轮中收集所有内容(老年代的回收频率要低得多)。
Sun/Oracle JVM有大量的性能调优选项。您可能想为此设置-XX:NewSize=60m
我可能对您想要设置的选项有所错误,可能有一个更适合这个问题的选项。然而,我认为调整这些GC标志比像其他答案中建议的仅仅减少总堆大小要好得多。
更新:这里是我在关于设置特定代堆大小方面找到的更多信息: 调整JVM:指定堆大小值

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