有没有办法在不使用时降低Java堆?
我目前正在开发一个Java应用程序,并致力于优化其内存使用。据我所知,我正在遵循正确垃圾收集的指导原则。然而,我的堆似乎处于其最大大小,即使它不是必需的 我的程序每小时运行一次资源密集型任务,当计算机不被人使用时。此任务使用相当大的内存块,但在任务完成后立即释放所有内存。NetBeans探查器显示内存使用情况如下所示: 我真的很想在不使用时把所有堆空间都还给操作系统。我没有理由在节目至少再过一个小时就什么都不做的情况下,把它吃光 这可能吗?谢谢 JVM不是这样工作的。你不能把它还给操作系统有没有办法在不使用时降低Java堆?,java,memory-management,heap,Java,Memory Management,Heap,我目前正在开发一个Java应用程序,并致力于优化其内存使用。据我所知,我正在遵循正确垃圾收集的指导原则。然而,我的堆似乎处于其最大大小,即使它不是必需的 我的程序每小时运行一次资源密集型任务,当计算机不被人使用时。此任务使用相当大的内存块,但在任务完成后立即释放所有内存。NetBeans探查器显示内存使用情况如下所示: 我真的很想在不使用时把所有堆空间都还给操作系统。我没有理由在节目至少再过一个小时就什么都不做的情况下,把它吃光 这可能吗?谢谢 JVM不是这样工作的。你不能把它还给操作系统 正
正如四年前编写的一些人所指出的那样,如果您为JVM提供适当的GC设置,就可以将内存返还给操作系统 您可能可以使用
-XX:MaxHeapFreeRatio
-这是GC收缩堆之前可用堆的最大百分比(默认值70)。也许将它设置得低一点(40或50?),然后使用System.gc()
可以让您获得所需的行为
但是,没有办法强迫这种情况发生,您可以尝试鼓励JVM这样做,但您不能在需要的时候将内存拉走。尽管上述方法可能会缩小堆,但内存不一定会直接返回操作系统(尽管在JVM的最新实现中确实如此。)一种可能性是让您的后台java应用程序每小时启动一个外部JVM实例来运行任务。这样,只有您的原始jvm应用程序才能在任务之间运行。如果您的应用程序在非活动期间处于静止状态,操作系统可能会为您交换这些页面,从而减轻它们对物理内存的压力
Java最好保密:-Xincgc 它确实会影响性能,但并不总是那么大。有时,这取决于你在做什么。
增量垃圾收集器将内存很好地交还给系统 简短版本:是的,你可以 长版本: Java/JVM如何管理内存 对于大多数应用程序,JVM默认值是可以接受的。看起来JVM希望应用程序只在有限的时间内运行。因此,它似乎无法自行释放内存 为了帮助JVM决定如何以及何时执行垃圾收集,应提供以下参数:
指定最小堆大小-Xms
指定最大堆大小–Xmx
-server
这对我来说还不够。我想要更多的控制!
如果上面提到的参数不够,您可能会影响JVM关于垃圾收集的行为
首先,您可以使用System.gc()
告诉VM您认为垃圾收集有意义的时间。其次,您可以指定JVM应该使用哪些垃圾收集器:
不同类型的垃圾收集器:
- 串行GC
命令行参数:
停止应用程序并执行GC-XX:+UseSerialGC
- 并行GC
命令行参数:
与应用程序并行运行次要集合。减少主要收集所需的时间,但使用另一个线程-XX:+UseParallelGC-XX:ParallelGCThreads=value
- 并行压缩GC
命令行参数:
与应用程序并行运行主要集合。使用更多CPU资源,减少内存使用-XX:+UseParallelOldGC
- CMS GC
命令行参数:
执行较小的收集,并且比串行GC更频繁,因此限制了应用程序的中断/停止-XX:+useComMarkSweepGC-XX:+UseParNewGC-XX:+cmsparallerRemarkenabled-XX:cmSinitiatingOccupencyFraction=value-XX:+useCSinitingOccupency
- G1
命令行参数:
实验性(至少在Java1.6中):尝试确保应用程序从未停止超过1s 范例-XX:+UnlockExperimentalVMOptions-XX:+UseG1GC
CMS GC
与System.GC()
相结合,可以获得最佳性能。因此,WebApp的内存使用量从1.8GB减少到了400-500MB左右
您可以在这里看到VisualVM的另一个屏幕截图,显示JVM如何释放内存并实际返回操作系统:
注意:我使用VisualVM的“执行GC”按钮来执行GC,而不是代码中的System.GC()
,因为消耗内存的计划任务只在特定时间启动,并且VisualVM更难捕获
进一步阅读