【问题标题】:Why SpringBoot continues to consume a lot of memory even after the load test is done为什么Spring Boot即使在负载测试完成后仍然会消耗大量内存
【发布时间】:2018-11-06 08:34:42
【问题描述】:

我的网站是一个部署在Linux服务器上的SpringBoot应用。我添加了 JMX,以便我可以通过 JVisualVM 监控这个网站。我运行它如下:

nohup java -Djava.rmi.server.hostname=10.25.161.45 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=22222 -jar sms-web.jar &

我开始负载测试,我可以看到内存消耗正在迅速增加,如红色矩形所示。这是可以理解的,因为在负载测试中建立和处理了很多 TCP 连接。但是在负载测试完成后,它仍然会继续消耗大量内存,有时会消耗到 800MB,如绿色矩形所示。封面下会发生什么?为什么会消耗这么多内存?

编辑:JVM 有没有办法通过 GC 来释放大量内存?

【问题讨论】:

    标签: spring-boot


    【解决方案1】:

    这对于任何 Java 应用程序来说都是很正常的行为。只要您的应用程序正在运行,就会创建对象,即使它没有被使用(正在检查/刷新线程池,...)。

    这意味着堆内存随着时间的推移而增加是正常的。但是,必要时,垃圾收集器将运行,并销毁任何不再使用的对象。这就是为什么您会在某些时候看到内存使用量明显下降的原因。

    现在,垃圾收集器只会在必要时运行。当您使用的内存(蓝线)接近允许使用的内存(橙线)时,通常会发生此过程。

    这说明了两件事:

    1. 它解释了负载测试期间的曲折线,这意味着垃圾收集器正在创建和销毁许多对象。
    2. 它解释了为什么您的应用程序在释放任何东西之前可以使用超过 800MB 的内存,因为它仍然允许使用更多的内存。

    现在,如果您认为您的应用程序允许消耗大约 1GB(或更多)内存是有问题的,那么您将不得不调整您的 JVM 设置,并可能将-Xmx 参数减少到合理的数量。确保在之后运行一些负载测试,以了解您的应用程序在减少最大允许内存时的行为,因为它可能会对您的应用程序的性能产生更大的影响,因为垃圾收集器必须更频繁地运行。

    【讨论】:

    • 嗨@g00glen00b,感谢您的努力。这要清楚得多。我还有一个顾虑。如果网站没有被使用,并且它的内存消耗在 100M 左右,那么我有信心以后有 100000 个请求进来。但是如果网站没有使用大约 800M 的内存,那么以后的巨大网络请求是否可以?
    • 此外,我认为在没有人使用该网站时将创建对象。但是为什么它使用高达800M?我发现如果我重新启动网站并且不执行任何负载测试,我看到内存消耗始终在上下 50M 左右,更不用说 800M。所以我想,负载测试确实影响了这一点。
    • @RobinSun 当然,如果它会消耗 800M 并且您稍后发出巨大的 Web 请求,那么垃圾收集器很快就会启动,并释放足够的内存。
    • @RobinSun loadtest 经常触发垃圾收集器,此外,最大内存量增加了,导致应用程序能够保留更多内存。但是,正如我在回答中提到的,您可以使用-Xmx 配置应用程序能够使用的最大允许堆内存。默认值由 JVM 确定,但可以达到 1GB,即使您的应用程序并不真正需要它。
    • @RobinSun 但是要真正确定是否没有内存泄漏,您应该更长时间地运行您的应用程序,以查看 GC 后的内存是保持在相同的值左右,还是增加了。
    猜你喜欢
    • 2011-05-10
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2010-11-09
    • 1970-01-01
    • 2010-12-09
    • 2018-05-05
    相关资源
    最近更新 更多