Java Tomcat 应用程序堆大小比已用堆大很多

Posted

技术标签:

【中文标题】Java Tomcat 应用程序堆大小比已用堆大很多【英文标题】:Java Tomcat application Heap size a lot larger then Used Heap 【发布时间】:2020-01-31 17:38:48 【问题描述】:

我正在开发一个 Java Webapp,它在 Tomcat 的 1GB 内存服务器上运行。

最近我们注意到,该应用占用了该服务器上的大部分内存 - 大约 83%。

我已经在我的个人计算机上使用 VisualVM 对应用程序进行了概要分析,该计算机具有更多 RAM。

VisualVM 显示大约 400MB 已用堆空间,分配的堆空间高达 1.4GB。

设置 -Xmx512m 允许我减少分配的堆空间,而不会对站点性能产生任何重大影响。

几个问题:

    这或多或少正常吗?为什么会这样? 可以做些什么来减少内存消耗?如果应用最终确实需要更多内存,使用 -Xmx 限制占用的内存量可能会成为问题。 如果操作系统需要另一个说 100mb 用于另一个进程,java 会释放这个内存供操作系统使用,因为它没有使用堆并且只分配堆,或者操作系统会运行到内存问题吗?

【问题讨论】:

如果您真的想更快地将内存释放回操作系统 (Shenandoah) 或至少启用 Java,最好的办法是选择不同的 GC -12 与this JEP,如果您打算继续使用G1 【参考方案1】:

按顺序回答您的问题。

    是的,这很正常。例如。当您以最大堆为 2 gb 启动服务器时,为 java 进程保留 2gb。应用程序可能会或可能不会完全使用它,但即使您在操作系统级别有更多可用内存,它也不能使用超过 2 GB,因为您已将最大使用量限制为 2 GB。此外,应用程序使用更少的内存(仅 100 MB)是正常的,在这种情况下,使用的堆大小将远小于总堆大小。 使用 -Xms 限制分配的内存,使用预期负载分析您的应用程序或从较低负载开始,查看应用程序是否运行良好,并分析内存使用情况。您需要通过改变配置的内存并保留所有其他参数来运行多个测试。多次运行之间的负载常数以找到最佳数量。 不,在服务器启动之前,jvm 不会将内存释放给另一个进程。启动服务器后,jvm 的最大内存配置将保留给 jvm 进程。

【讨论】:

设置 -Xms 没有多大作用。该应用程序以内存集启动,但随后几乎立即拿起分配的堆。这根本没有任何负载,只是空闲的应用程序。压力不会增加那么多使用的堆(如果是 50-100mb) 这是一个好兆头。减少堆分配并保持其大小适中。另外,我建议找到最低限度的号码。需要运行您的应用程序并查看它是否可以承受负载。此外,尝试找到扩大负载与内存需求的比率。我希望您也在考虑其他因素,例如 cpu、连接池、网络带宽等。

以上是关于Java Tomcat 应用程序堆大小比已用堆大很多的主要内容,如果未能解决你的问题,请参考以下文章

已用堆大小不断增加

从 Java 堆转储中获取已使用和释放的内存

ES优化 内存设置

180Java用堆实现从列表中获取第k小(或大)的元素

180Java用堆实现从列表中获取第k小(或大)的元素

关于tomcat内存设置