如何降低Java中的已提交内存使用量

huangapple go评论66阅读模式
英文:

How to reduce committed memory usage in Java

问题

我使用Java Swing创建了一个简单的GUI软件。面板上有一个按钮,点击该按钮将触发生成一个具有巨大大小的ArrayList。每次我点击这个按钮,我的Java程序的内存使用量都会在任务管理器中显著增加,因此我怀疑是否存在内存泄漏问题。

然后,我通过Jprofile调查了我的程序,并发现如下所示的情况(以下为图片):

如何降低Java中的已提交内存使用量
如何降低Java中的已提交内存使用量

如图片所示,在巨大的ArrayList变得无用之后,GC机制似乎工作正常(真的吗?)。然而,我希望我的程序能减少已提交的内存大小(而不是更多的可用内存),这样当我的程序处于空闲状态时,总内存使用量会减少。

我不太理解Java的内存使用情况,有人能向我解释一下吗?我如何实现我的目标,或者我的图片所示情况是不可避免的?

英文:

I use Java Swing to create a simple GUI software. There exists a button on the panel that will trigger the generation of an ArrayList with a huge size. Each time I click this button the memory usage of my java program will increase significantly on my task manager, therefore I doubt that whether there exists the memory leakage problem.

After, I investigate my program by Jprofile and found (pictures below):

如何降低Java中的已提交内存使用量
如何降低Java中的已提交内存使用量

As the pictures show, after the huge ArrayList is useless, the GC mechanism seems to work properly (really?). However, I want my program to reduce the committed size (instead of more free size) so that the total memory usage would be decreased when my program is idle.

I do not understand the Java memory usage, can anyone explain to me? How can I achieve my goal or the situation of my pictures is inevitable?

答案1

得分: 2

然而,我希望我的程序能够减少已提交的内存大小(而不是增加更多的可用大小),这样当我的程序处于空闲状态时,总内存使用量将会减少。

限制JVM已提交内存使用的简单方法是使用-Xmx来设置最大堆大小。问题在于,如果你过于严格地限制堆大小,可能会触发OutOfMemoryError

让JVM“归还”内存是另一回事。通常,如果JVM认为堆变得过大,它会将一些内存归还给操作系统。然而,用于此的默认GC设置意味着在JVM / GC释放内存之前,它会经历多个GC周期。(典型的Java应用程序的内存需求波动,让GC不断调整堆的大小变得低效。)

这个问答对这个过程有更详细的描述:

值得注意的是,重新调整大小的决策通常发生在完整GC之后。但是,一个空闲的程序不会产生太多的垃圾,可能根本不会经常(甚至根本不会)触发GC。可能需要通过调用System.gc()手动运行GC,以“鼓励”它释放内存。但这样做也有不利之处:

总的来说,我的建议是为-Xmx设置一个合理的值,然后不再担心。如果系统性能变得太差(例如由于Java使用过多内存),就增加内存或购买一台可以添加更多内存的“新”机器。(通过谷歌,我在2分钟内找到了一台带有8GB RAM的翻新低端台式电脑,售价为199澳元。)

英文:

> However, I want my program to reduce the committed size (instead of more free size) so that the total memory usage would be decreased when my program is idle.

The easy way to limit committed memory usage for a JVM is to to use -Xmx to set the maximum heap size. The problem is that if you limit the heap size too severely you are liable to trigger OutOfMemoryErrors.

Getting the JVM to give back memory is another matter. A JVM typically will give some memory back to the OS if it thinks that the heap has gotten too large. However, the default GC settings for this mean that the JVM / GC takes multiple GC cycles before it will give memory back. (A typical Java application's memory demand fluctuates, and it is inefficient for the GC keep resizing the heap larger and smaller again.)

This Q&A describes the process in more detail:

It is worth noting that the resize decision making (typically) happens after a Full GC. But a program that is idle won't be generating much garbage, and probably won't trigger the GC often, if at all. It might be necessary to manually run the GC by calling System.gc() to "encourage" it to give back memory. But there are downsides in doing that too:

Overall, my advice would be to set a reasonable value for -Xmx and stop worrying. If system performance gets too bad (e.g. due to Java using too much memory), buy more memory or a "new" machine that can take more memory. (2 minutes with Google found me a refurbished low-end desktop PC with 8GB RAM for AU$ 199.)

huangapple
  • 本文由 发表于 2020年8月30日 19:03:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63656761.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定