当前位置: 首页 > 知识库问答 >
问题:

JVM堆未释放

宰宣
2023-03-14

我是分析Java记忆问题的新手。所以请原谅我这个问题看起来很天真

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

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

我正在使用visualVM监控使用情况:以下是我看到的

问题是,即使应用程序没有接收任何要处理的数据,使用的内存也不会下降。当应用程序启动时,使用的空间开始变小(大约1GB),但随着应用程序的运行而增加。然后用过的记忆永远不会消失。我的问题是,为什么即使应用程序中没有发生重大处理,使用的堆内存也不会下降,以及可以设置什么配置来纠正它。我的理解是,如果应用程序不进行任何处理,那么使用的堆应该更少,在这种情况下,可用堆内存(或最大堆)应该保持不变(3GB)。

共有1个答案

鞠泰平
2023-03-14

这是一种完全正常的趋势,即使您认为它没有被使用,也可能有线程在执行任务时创建了未被引用的对象,这些对象有资格进行下一次GC,但只要不存在次要/主要GC,它们就会在堆中占据越来越多的空间,因此它会一直上升,直到触发GC,然后您就可以获得正常的堆大小,依此类推。

异常趋势是一样的,但在GC之后,堆大小将高于前一个GC之后的堆大小,这里不是这种情况。

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

下面是一个典型的内存泄漏趋势示例:

正如您所看到的,两个GC之间的起始堆大小发生了变化,新的起始堆大小高于上一个,这可能是由于内存泄漏。

 类似资料:
  • 我有一个Springboot应用程序,Mule作为微服务在docker容器中运行。即使空闲时也需要大约700MB。注意到JVM分配了380 MB的堆,这是使用参数提供的最大堆。虽然分配了最大堆,但微服务在空闲时只使用大约50 MB。问题是如何从JVM释放未使用的内存。 似乎减少MaxHeapFreeRatio我们可以要求JVM在有更多可用内存时收缩。然而没有太大区别,JVM也没有释放内存。但是当我

  • 我来自C/C++背景,在这里一个进程内存分为: null 我想把我的注意力集中在这一点上,当我阅读JVM中的堆和堆栈时,我们是在谈论堆栈和堆的概念吗?并且整个JVM的实际内存驻留在堆上(这里指的是堆的C++概念)?

  • 问题内容: 每当加载一个类时,什么存储在堆中以及什么存储在堆栈中? 线程也驻留在哪里? 问题答案: 引用类型在堆中。 任何原始类型的数据和对堆上值(方法的参数/局部变量)的引用都在堆栈上。 每个线程都有自己的堆栈。 应用程序中的所有线程共享同一堆。

  • 问题内容: 在阅读有关该主题的已问问题和大量谷歌搜索之后,我仍然无法清楚了解 -Xms 选项 我的问题是:和之间有什么区别? 现在,我有以下答案: 唯一的区别是在应用程序运行期间将运行的垃圾回收数量和内存分配数量。我对吗 ? 这是我获得此答案的原因: 将选项设置为不会导致我的应用程序在启动后真正占用物理内存。我想这与现代OS虚拟内存管理和惰性页面分配有关。(我注意到,在Linux上由top或Win

  • 这里和这里都有类似的问题,但对JVM参数的更改都没有让我找到相同的解决方案。我只是想减少JVM未使用的堆大小,以便它更接近实际使用情况(将其释放给操作系统)。我一直在使用YourKit来分析内存使用情况,它通常如下所示: 我正在运行智能Ij IDEA社区版64位,在Windows 7 64位,8 GB RAM上运行。我已经编辑了.文件在这里找到: 与上述链接中提到的建议。第一个链接的答案实际上是错

  • 因此,我知道对堆栈中分配的变量调用会导致无效指针错误。 在ED指针中,在实际指针之前分配8个字节,以保留关于指针大小的信息。因此,我想知道是否在一个结构之前做了一个,然后在该结构上调用free,是否可以释放该结构(当然,这偏离了分配这8个字节是所做的唯一额外的事情的假设)。 我想我的最后一个问题是,堆栈变量分配和堆分配之间是否有真正的区别(就后端对内核的调用而言)。