我们运行一个我们没有开发的Java应用程序。 此应用程序为某些任务使用了大量内存,具体取决于操作的数据,最高可达4GB。在其他时候,只需要很少的内存,大约300MB。
一旦JVM抓取了大量内存,收集垃圾需要很长时间,甚至更长时间才能将内存返回给操作系统。这对我们来说是一个问题。
发生的情况如下:JVM需要大量内存用于任务,并获取4GB Ram以创建4GB堆。然后,处理完成后,内存仅填充30%-50%。更改内存消耗需要很长时间。当我触发GC(通过jConsole)时,堆缩小到500MB以下。另一个触发GC,堆缩小到200MB。有时候内存会返回系统,通常不会。
以下是VisualVM的典型截图。收集堆(使用堆下降)但堆大小保持不变。只有当我通过“执行GC”-Button触发GC时,堆大小才会减小。
我们如何调整GC以更早地收集内存?性能和GC-Pause-Times对我们来说不是什么大问题。我们宁愿让更多更早的GC来及时减少内存。 我们如何调整JVM以将内存释放回操作系统,使JVM使用的内存更小?
我知道-XX:MinHeapFreeRatio和-XX:MaxHeapFreeRatio,这有点帮助,但用VisualVM观察堆向我们表明,它并不总是服从。我们将MaxHeapFreeRatio设置为40%并在VisualVM中看到堆只填充到大约10%。
我们无法减少最大内存(-Xmx),因为有时候,在短时间内,需要大量内存。
我们不限于特定的GC。因此,可以应用任何能最好地解决问题的GC。
我们使用Oracle Hotspot JVM 1.8
答案 0 :(得分:1)
我假设您使用HotSpot JVM。
然后,您可以使用JVM-Option -XX:InitiatingHeapOccupancyPercent=n
(0< = n< = 100)强制JVM更频繁地进行垃圾回收。当您将n设置为0时,应该进行常量GC。但我不确定这是否对您的应用程序响应时间有好处。