本文介绍了JVM堆未释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始分析Java中的内存问题.所以请原谅我这个问题是否天真

I am new to analyzing memory issues in Java. So pardon me if this question seems naive

我的应用程序运行时设置了以下JVM参数:

I have application running with following JVM parameters set:

-Xms3072m -Xmx3072m
-XX:MaxNewSize=1008m -XX:NewSize=1008m
-XX:PermSize=224m -XX:MaxPermSize=224m -XX:SurvivorRatio=6

我正在使用visualVM监视使用情况:这就是我所看到的

I am using visualVM to monitor the usage : Here is what I see

问题在于,即使应用程序未接收到任何数据进行处理,使用的内存也不会减少.启动应用程序时,使用的空间开始时很小(大约1GB),但随着应用程序的运行而增加.然后使用的内存就永远不会下降.我的问题是,即使在应用程序中没有进行任何重大处理的情况下,为什么使用的堆内存也不会减少,并且可以设置哪些配置来对其进行纠正.我的理解是,如果应用程序未进行任何处理,则在这种情况下使用的堆应该更少,可用堆内存(或最大堆)应该保持不变(3GB).

The problem is, even when the application is not receiving any data for processing, the used memory doesn't go down. When the application is started, the used space starts low (around 1GB) but grows as the application is running. and then the used memory never goes down.My question is why the used heap memory doesn't go down even when no major processing happening in application and what configurations can be set to correct it.My understanding is if application is not doing any processing then the heap used should be less and heap memory available ( or max heap) should remain the same (3GB) in this case.

推荐答案

这是一个完全正常的趋势,即使您认为未使用它,也可能有线程正在运行执行创建对象的任务,这些任务一旦创建就成为unreferenced.任务完成后,这些对象才有资格使用下一个GC,但是只要没有minor/major GC,它们就会在堆中占用越来越多的空间,因此它会上升直到触发GC,然后您将获得正常的堆大小,依此类推.

This is a totally normal trend, even if you believe that it is not used there are probably threads running doing tasks that create objects that are unreferenced once the tasks are done, those objects are eligible for the next GC but as long as there is no minor/major GC they take more and more room in your heap so it goes up until a GC is triggered then you get the normal heap size and so on.

异常趋势是一样的,但是在GC之后,堆大小将比前一个GC之后的堆大小要大,这不是这种情况.

An abnormal trend will be the same thing but after a GC the heap size would be higher than the heap size just after the previous GC which is not the case here.

您真正的问题是,当我不接收任何要处理的数据时,我的应用程序正在做什么?为此,线程转储应该有所帮助,可以启动jcmd获取PID,然后启动jstack $pid获取线程转储.

Your real question is more what my application is doing when is not receiving any data to process? For that a thread dump should help, you can launch jcmd to get the PID then launch jstack $pid to get the thread dump.

以下是发生内存泄漏时典型趋势的示例:

Here is an example of a typical trend in case of memory leak:

您可以看到两个GC之间的起始堆大小已更改,新的起始堆大小大于上一个,这可能是由于内存泄漏所致.

As you can see the starting heap size has changed between two GC, the new starting heap size is higher than the previous one which may be due to a memory leak.

这篇关于JVM堆未释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 01:45