我有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。
3条答案
按热度按时间huwehgph1#
操作系统报告的驻留内存并不能告诉你是哪个组件在消耗它,你必须收集额外的数据来确定进程的哪个部分在增长
你得追踪
pmap -x <pid>
t8e9dugd2#
我也遇到过这种情况,经过长时间的研究,我找到了解决方案。基本上,对于我的情况,这只是在jar调用上设置xms和xmx参数的问题,迫使GC不断地动作。
piwo6bdm3#
这里公认的答案可能会对你有所帮助。
Java进程的常驻内存使用(RSS)不断增长
为tomcat9 JVM设置这些环境变量有助于我自己的情况,即低使用率、低内存的应用程序仍然会根据Linux上的top继续使用RSS。这些环境变量禁用了一些释放内存的动态Glibc策略,在某些Tomcat场景中它不会这样做。
字符串
当前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的