7

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

之后用户做了一些非常繁重的工作,然后应用程序使用 2G。然后用户退出应用程序,再次显示登录屏幕(应用程序尚未关闭)。此时应用程序使用的实际内存为 64MB(假设这是完美的内存管理应用程序),但在 OS 中这个应用程序仍然使用 2G 的 RAM,我可以在 OS 的资源监视器上看到它。

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

我的意思是当我的应用程序需要使用 64MB 内存时,操作系统只给它 64MB,当它需要 2GB 内存时,操作系统给它 2GB,之后它需要 64MB 内存,然后操作系统又给它 64MB,我不希望它浪费 2000MB - 64MB = 1936MB。

我可以这样做吗?

谢谢,

4

5 回答 5

5

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

不,你不能。

在某些情况下,GC 会自行将内存释放回操作系统,但我不知道有任何 JVM 允许应用程序告诉 GC 这样做。最重要的是,GC 对此相当保守,因为......作为一般规则...... JVM 将使用更多内存更有效地运行,并且不断向操作系统请求/返还内存效率低下。


请注意,GC 调整选项-XX:MaxHeapFreeRatio可用于指定在 GC 归还内存之前可用堆与已用堆的最大比率。然而,也有并发症。例如,并非所有可用的 GC 都尊重此选项。如果你打算尝试这种方法,我建议你做一些研究......不要指望奇迹。

于 2012-08-12T04:06:45.910 回答
5

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

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

-XX:UseSerialGC -Xms16M -Xminf=5 -Xmaxf=10
于 2013-03-20T21:38:10.890 回答
2

热点中的 serialgc 将返回内存……至少它曾经如此。你的表现会一蹶不振。

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

最好的答案是,你为什么担心?如今,内存非常便宜,而免费内存就是浪费内存。这真的是个问题吗?无论如何,操作系统都会将多余的未使用内存分页到磁盘。最好的答案是忽略它。:)

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

编辑:

我刚刚在 JDK1.7u6 中注意到,使用具有小 Xms 和大 Xmx 的 G1GC,垃圾收集器将在释放多余对象的几次垃圾收集后减小堆的大小。

于 2012-08-12T04:14:40.453 回答
1

您可以处理对象并建议垃圾收集器完成其工作,但如果 GC 认为没有必要,则该请求将被忽略。所以总而言之,“不”。

请注意分配给 Java 应用程序的内存。在应用程序之前设置。启动,并且不可调节。

于 2012-08-12T03:04:53.920 回答
0

尝试将部分代码分叉到单独的线程,并在不再需要时将其丢弃。

于 2013-08-05T17:54:00.637 回答