我是分析Java中内存问题的新手。如果这个问题看起来很幼稚,请原谅我
我运行应用程序并设置了以下JVM参数:
-Xms3072m -Xmx3072m
-XX:MaxNewSize=1008m -XX:NewSize=1008m
-XX:PermSize=224m -XX:MaxPermSize=224m -XX:SurvivorRatio=6
我使用visualVM来监控用法:这是我看到的
问题是,即使应用程序没有接收任何数据进行处理,使用的内存也不会下降。启动应用程序时,已用空间从低(约1GB)开始,但随着应用程序的运行而增长。然后用过的内存永远不会消失。 我的问题是,即使在应用程序中没有发生重大处理以及可以设置哪些配置来纠正它,所使用的堆内存也不会下降。 我的理解是,如果应用程序没有进行任何处理,那么使用的堆应该更少,并且在这种情况下堆内存可用(或最大堆)应该保持不变(3GB)。
答案 0 :(得分:5)
这是一个完全正常的趋势,即使你认为它没有被使用,也许线程正在运行执行任务,一旦完成任务就创建unreferenced
对象,这些对象有资格进行下一个GC但是只要没有minor/major GC
它们就会在你的堆中占用越来越多的空间,所以它会一直上升直到GC被触发然后你得到正常的堆大小等等。
异常趋势将是相同的,但在GC之后,堆大小将高于之前GC之后的堆大小,而不是这里的情况。
真正的问题是我的应用程序在没有接收任何数据时要处理的更多内容?为此,线程转储应该有帮助,您可以启动jcmd
以获取PID,然后启动jstack $pid
以获取线程转储。
以下是内存泄漏情况下典型趋势的示例:
正如您所看到的,两个GC之间的起始堆大小已经更改,新的起始堆大小高于前一个大小,这可能是由于内存泄漏造成的。