Spring Boot 为什么RES内存对于Java进程保持缓慢增长,即使对于开箱即用的Sping Boot 管理员也是如此?

qybjjes1  于 2023-11-17  发布在  Spring
关注(0)|答案(3)|浏览(216)

我有23个Java进程运行在一台32 GB的机器上。没有进程指定JVM内存参数,如Xmx。java -XX:+PrintFlagsFinal -version | grep MaxHeapSize报告最大默认堆大小为8 GB,如预期的那样。
每个进程都运行嵌入式Tomcat(Sping Boot 应用程序(大多数在v2.3.4)),除了一个是运行三个WAR的独立tomcat 9示例。(通常一个用户和10分钟使用一天)。它们不是内存或CPU密集型的。其中一个是Sping Boot admin,另一个是Spring Cloud的Eureka 服务注册表。对于这两个,我只有一个main方法来简单地引导Spring Boot应用程序。
然而,RES内存(如顶部所示)对于每个进程都在逐渐增加。例如,Sping Boot 服务注册表在过去12小时内已从1.1 GB增加到1.5 GB。所有进程在RES中均显示类似的小幅增加,但在同一12小时内,总增加量使可用内存减少了2 GB。这与之前12小时相同(依此类推)直到当前可用内存现在只有4.7GB。
我担心的是,我继续看到这种趋势(即使没有应用程序使用)。内存从未从应用程序中释放,因此总的可用内存继续减少。这是正常的吗?因为也许每个JVM都看到OS中的内存仍然可用,并且可以使用8 GB堆空间?JVM是否会在某个时候停止占用内存,比如一旦达到OS的可用内存阈值?或者它会一直持续到所有空闲内存都用完为止?

更新

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

huwehgph

huwehgph1#

操作系统报告的驻留内存并不能告诉你是哪个组件在消耗它,你必须收集额外的数据来确定进程的哪个部分在增长
你得追踪

  • java堆和元空间使用--您可以使用JMC、gc日志和许多其他java监视工具来监视它
  • jvm off-heap use - NMT
  • 直接字节缓冲器使用-MX beans,也可通过JMC获得
  • 由Map文件使用-pmap -x <pid>
  • 由本地库使用,例如通过JNI使用-难以监控
t8e9dugd

t8e9dugd2#

我也遇到过这种情况,经过长时间的研究,我找到了解决方案。基本上,对于我的情况,这只是在jar调用上设置xms和xmx参数的问题,迫使GC不断地动作。

piwo6bdm

piwo6bdm3#

这里公认的答案可能会对你有所帮助。
Java进程的常驻内存使用(RSS)不断增长
为tomcat9 JVM设置这些环境变量有助于我自己的情况,即低使用率、低内存的应用程序仍然会根据Linux上的top继续使用RSS。这些环境变量禁用了一些释放内存的动态Glibc策略,在某些Tomcat场景中它不会这样做。

export MALLOC_ARENA_MAX=4
export MALLOC_MMAP_THRESHOLD_=131072
export MALLOC_TRIM_THRESHOLD_=131072
export MALLOC_TOP_PAD_=131072
export MALLOC_MMAP_MAX_=65536

字符串
当前JVM中的一个解决方法(至少对于Java 11)是使用System.trim_native_heap选项来jcmd
sudo jcmd <pid> System.trim_native_heap
有一些关于Glibc不向操作系统返回内存的问题的讨论,看起来你可能正在使用Linux。
https://bugs.openjdk.org/browse/JDK-8269345
https://bugs.openjdk.org/browse/JDK-8293114
https://marc.info/?l=openjdk-serviceability-dev&m=168879617126137

相关问题