在运行时释放OS的java内存。

时间:2012-08-12 03:02:07

标签: java jvm

假设我有一个Swings Java应用程序, 我设置最小堆是64MB和最大堆2GB, 当用户启动应用程序时,登录屏幕 将显示,此时应用程序使用64MB,权限? 从我的Windows 7中,我可以看到java应用程序被分配了64MB 从操作系统的内存资源监视器(实际上,它超过64MB,因为JVM需要一些内存来完成它的任务)。

之后,用户执行了一些非常繁重的工作,然后应用程序使用2G。 然后用户注销应用程序,再次显示登录屏幕(应用程序尚未关闭)。这时应用程序的真实内存 使用64MB(假设这是完美的内存管理应用程序), 但是对于操作系统,这个应用程序仍在使用2G的RAM,我可以在操作系统的资源监视器上看到它。

我希望我的应用程序在不需要使用大内存时将内存释放到操作系统。我可以在运行时使用java app吗?

我的意思是当我的应用程序需要使用64MB的Ram时, 操作系统只给它64MB, 当它需要2GB的RAM时,操作系统会给它2GB, 之后它需要64MB的RAM然后操作系统再次给它64MB, 我不想浪费2000MB - 64MB = 1936MB。

我能这样做吗?

谢谢,

5 个答案:

答案 0 :(得分:5)

  

我希望我的应用程序在不需要使用大内存时将内存释放到操作系统。我可以在运行时使用java app吗?

不,你不能。

在某些情况下,GC会根据自己的意愿将内存释放回操作系统,但我不知道任何允许应用程序告诉GC执行此操作的JVM。最重要的是,GC在这方面相当保守,因为......作为一般规则...... JVM将以更多内存更高效地运行,并且不断向OS请求/回馈内存效率低下。


请注意,GC调整选项-XX:MaxHeapFreeRatio可用于指定GC将释放内存之前的可用堆的最大比率。但是,有并发症。例如,并非所有可用的GC都遵循此选项。如果你打算尝试这种方法,我建议你做一些研究......不要指望奇迹。

答案 1 :(得分:5)

我已发布测试结果over there。基本上,MaxHeapFreeRatio不受每个GC实现的尊重,并且,为了使其更糟糕,似乎有必要存在足够的堆活动以便及时触发它,即。可能是你需要2次完整的GC运行来实际释放内存到操作系统。如果你有一个X GB的突发内存占用,那么你可能需要分配该数量的1或2倍才能触发堆缩小。或者您手动调用System.gc()。

如果性能不是问题,并且内存占用非常重要,请尝试:

-XX:UseSerialGC -Xms16M -Xminf=5 -Xmaxf=10

答案 2 :(得分:2)

热点中的serialgc会给内存回复......至少它曾经用过。你的表现将会下降。

IBM J9 jvm中的所有垃圾收集器都将释放内存。我不确定这个jvm是免费下载的......

最好的答案是,你为什么担心?这些天内存很便宜,免费内存浪费了内存。这实际上是个问题吗?操作系统无论如何都会将额外的未使用内存分页到磁盘。最好的答案是忽略它。 :)

您也可以考虑使用谷歌搜索堆外存储,也许是Teracotta / eh缓存。

编辑:

我刚刚在JDK1.7u6中注意到,使用带有小Xms和大型Xmx的G1GC,垃圾收集器将在一些垃圾收集后减少堆的大小,其中多余的对象已被释放。

答案 3 :(得分:1)

您可以处置对象并建议垃圾收集器执行其工作,但如果GC认为没有必要,则会忽略该请求。总而言之,'不'。

请注意分配给Java应用程序的内存。在应用程序之前设置。开始,不可调整。

答案 4 :(得分:0)

尝试将代码的一部分分配给一个单独的线程,并在不再需要它时将其处理掉。