(Note当我说“JVM”时,我实际上是指“热点”,而且我正在运行最新的Java1.6更新。)
示例情况:
我的JVM在运行时将-Xmx设置为1gb。当前,堆分配了500 mb,其中450 mb已被使用。程序需要在堆上再加载200 mb。当前,堆中有300 mb的“可收集”垃圾(我们假设它们都在最老的代中)。
在正常操作下,JVM会将堆增长到700 mb左右,并在到达时进行垃圾收集。
在这种情况下,我希望JVM先gc,然后分配新的东西,这样我们最终的堆大小保持在500 mb,使用的堆大小为350 mb。
是否有JVM参数组合可以实现这一点?
4条答案
按热度按时间bz4sfanl1#
您可以尝试指定
-XX:MinHeapFreeRatio
和-XX:MaxHeapFreeRatio
来控制堆扩展和收缩:-XX:MinHeapFreeRatio
-当层代中的可用空间百分比福尔斯此值时,将扩展层代以满足此百分比。默认值为40。-XX:MaxHeapFreeRatio
-当层代中的可用空间百分比超过此值时,层代将收缩以满足此值。默认值为70。您可能还想通过指定
-XX:+UseConcMarkSweepGC
来试验并发GC。根据您的应用程序,它可以以额外的CPU周期为代价来保持堆大小较低。JVM会在最佳情况下使用您指定的可用内存。您可以指定一个较低的内存量(如
-Xmx768m
)来控制它,它可能会运行良好,但在重负载情况下会增加内存不足的风险。实际上,使用更少内存的唯一方法是编写使用更少内存的代码:)cl25kdpy2#
更新Java 15增加了两个收集器。
ZGC
中的一些相关选项包括:-XX:+UseZGC
使能ZGC-XX:+ZProactive
和-XX:+ZUncommit
都是默认启用的。ZGC将主动尝试释放垃圾对象并将释放的内存释放给操作系统。其余选项调整其执行的积极程度。-XX:ZCollectionInterval=seconds
GC运行的频率。设置为几秒以确保垃圾尽可能快地被清除。(默认值为0,即不能保证GC会运行。)-XX:ZUncommitDelay=seconds
设置在取消提交之前堆内存必须处于未使用状态的时间(秒)。默认情况下,此选项设置为300(5分钟)。设置较低的值可更快地收回内存-XX:SoftMaxHeapSize
每当应用程序使用的内存超过此限制时,GC将更频繁地触发。(这可能是OP正在寻找的答案。)-XX:SoftRefLRUPolicyMSPerMB
不确定此选项的相关频率,但它控制某些缓存对象在内存中保留的时间。原始答案HotSpot中有四个(实际上是五个)不同的垃圾收集器,您可以为每个垃圾收集器选择不同的选项。
-XX:MinHeapFreeRatio
和-XX:MaxHeapFreeRatio
,这让你或多或少地直接控制行为。-XX:+UseParallelOldGC
)有-XX:MaxGCPauseMillis=<millis>
和-XX:GCTimeRatio=<N>
。设置较短的最大暂停时间通常会导致收集器缩小堆。但是,如果暂停时间已经很短,堆不会变小。OTOH,如果最大暂停时间设置得太短,应用程序可能会将所有时间都花在收集上。设置较低的gc时间比率通常也会使堆变小。您是在告诉gc您“We“我们愿意用更多的CPU时间来收集,以换取更小的堆。然而,这只是一个提示,可能没有任何效果。在我看来,为了最小化堆的大小,并行收集器几乎是不可调的。如果您让它运行一段时间,并且应用程序的行为保持不变,则它会自动调整。-XX:+UseConcMarkSweepGC
)通常需要一个更大的堆来实现其低暂停时间的主要目标,因此我将不讨论它。-XX:+UseG1GC
)不像旧的收集器那样愚蠢。我发现它会自己选择一个较小的堆大小。它有很多调整选项,尽管我才开始研究它们。-XX:InitiatingHeapOccupancyPercent
、-XX:G1HeapWastePercent
、-XX:G1ReservePercent
和-XX:G1MaxNewSizePercent
可能会感兴趣。看一看list of
java
flags。hc2pp10m3#
您可以像通常一样在分配额外的200MB对象之前调用
System.gc()
方法,但这只是对JVM的一个提示,它可以或不可以遵循,而且在任何情况下,您都不知道何时会发生这种情况。正如文档中所述,这是一个尽力而为的请求。顺便说一下,考虑到垃圾收集是一个繁重的操作,所以如果没有特定的需要这样做,只是不要试图强迫它。
才知道:如果您设置
-Xmx1G
,那么您将告诉JVM 1GB是堆的最大空间,由于您指定了该值,我不明白为什么它应该尝试保持低,如果它知道1GB将仍然可以(我们是在内存管理语言的环境中)。如果您不'I don“我不希望堆增加那么多,只要降低最大值,这样它就可以在分配新对象之前强制执行GC,否则为什么要告诉它使用1GB?c8ib6hqw4#
我建议在这里看一下:
http://www.petefreitag.com/articles/gctuning/