为什么即使对于开箱即用的Spring引导管理,Java进程的RES内存也在缓慢增长?

为什么即使对于开箱即用的Spring引导管理,Java进程的RES内存也在缓慢增长?,java,linux,spring-boot,memory,jvm,Java,Linux,Spring Boot,Memory,Jvm,我有23个Java进程在一台32GB的机器上运行。没有进程指定JVM内存参数,例如Xmxjava-XX:+PrintFlagsFinal-version | grep MaxHeapSize报告最大默认堆大小为预期的8GB 每个进程都运行嵌入式Tomcat(Spring Boot应用程序(大多数为V2.3.4版本)),除了一个是运行三场战争的独立Tomcat 9实例。这些应用的使用率很低(通常是一个用户,每天使用10分钟)。它们不是内存或CPU密集型的。其中一个是SpringBootAdmin,

我有23个Java进程在一台32GB的机器上运行。没有进程指定JVM内存参数,例如Xmx
java-XX:+PrintFlagsFinal-version | grep MaxHeapSize
报告最大默认堆大小为预期的8GB

每个进程都运行嵌入式Tomcat(Spring Boot应用程序(大多数为V2.3.4版本)),除了一个是运行三场战争的独立Tomcat 9实例。这些应用的使用率很低(通常是一个用户,每天使用10分钟)。它们不是内存或CPU密集型的。其中一个是SpringBootAdmin,另一个是SpringCloud的Eureka服务注册表。对于这两个,我只有一个简单引导Spring引导应用程序的主方法

然而,
RES
每个进程的顶部显示的内存一直在逐渐增加。例如,SpringBootServiceRegistry在过去12小时内从1.1GB增加到1.5GB。所有进程的
RES
都有类似的小幅度增加,但总的增加使可用内存在同一12小时内减少了2 GB。这与前12个小时的情况相同(以此类推),直到目前的可用内存只有4.7GB

我担心的是,我会继续看到这种趋势(即使没有应用的使用)。内存永远不会从应用程序中释放,因此总可用内存将继续减少。这是否正常,因为可能每个JVM都看到操作系统中仍然有可用的内存,并且8GB堆空间对其可用?JVM是否会在某个时刻停止占用内存,比如一旦达到操作系统可用内存阈值?或者它会一直持续到所有可用内存被使用为止

更新


大多数应用程序使用的堆小于200MB,但堆大小为1.5-2.8GB。堆最大值为8GB。

操作系统报告的驻留内存不会告诉您哪个组件正在使用它。您必须收集额外的数据,以确定流程的哪一部分正在增长

你必须追踪

  • java堆和元空间的使用—您可以使用、gc日志和许多其他java监视工具来监视这一点
  • jvm堆外使用-
  • 直接字节缓冲区使用-,也可通过JMC获得
  • 由映射文件使用-
    pmap-x
  • 由本机库使用,例如通过JNI使用-难以监控

    • 我也面临着这种情况,经过长时间的研究,我找到了解决办法。基本上,就我的情况而言,这只是在jar调用上设置xms和xmx参数的问题,迫使GC不断动作。

      您的问题似乎是GC(我假设您使用的是
      G1GC
      )不会将内存释放回操作系统。。。在这种情况下,您可能会从中受益,但只能从java-12中受益,或者切换到可以做到这一点的GC。也许可以找到更多的细节——它谈到了docker,但触及了释放内存的总体思路