我是分析 Java 内存问题的新手。如果这个问题看起来很幼稚,请原谅我
我的应用程序运行时设置了以下 JVM 参数:
-Xms3072m -Xmx3072m
-XX:MaxNewSize=1008m -XX:NewSize=1008m
-XX:PermSize=224m -XX:MaxPermSize=224m -XX:SurvivorRatio=6
我正在使用 visualVM 来监控使用情况:这是我所看到的
问题是,即使应用程序没有接收到任何要处理的数据,使用的内存也不会减少。当应用程序启动时,已用空间一开始很低(大约 1GB),但随着应用程序的运行而增加。然后使用的内存永远不会下降。 我的问题是为什么即使在应用程序中没有发生主要处理时使用的堆内存也不会下降,以及可以设置哪些配置来纠正它。 我的理解是,如果应用程序没有进行任何处理,那么使用的堆应该更少,并且在这种情况下可用堆内存(或最大堆)应该保持不变 (3GB)。
最佳答案
这是一个完全正常的趋势,即使您认为它没有被使用,也可能有线程正在运行以执行创建未引用
对象的任务,一旦任务完成,这些对象就有资格下一次 GC,但只要没有 minor/major GC
,它们就会在您的堆中占用越来越多的空间,因此它会一直上升,直到触发 GC,然后您才能获得正常的堆大小,依此类推。
异常趋势是一样的,但是在 GC 之后堆大小会高于上一次 GC 之后的堆大小,而这里不是这种情况。
您真正的问题更多是当我的应用程序没有收到任何要处理的数据时正在做什么?为此,线程转储应该有所帮助,您可以启动 jcmd
以获取 PID,然后启动 jstack $pid
以获取线程转储。
这是内存泄漏情况下的典型趋势示例:
如您所见,起始堆大小在两次 GC 之间发生了变化,新的起始堆大小大于前一个,这可能是由于内存泄漏。
关于java - JVM 堆未释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37684928/