Java 8应用程序在Wildfly 8.2.1上部署时,Metaspace内存消耗问题

9

问题描述

我注意到我们的一个Java8应用程序在Wildfly 8.2.1上的每次部署都会从Metaspace内存池中使用大约30-40 MB。这很好,但问题在于,一旦我重新部署同一个应用程序,Metaspace内存使用量就会增加相同的30-40 MB,而旧的已分配内存不会被释放。

我甚至可能都没有注意到它,但问题是我们有大约20个应用程序,有时我需要同时重新部署其中的10个。这反过来又导致了一个可怕的情况。

enter image description here 基本上,所显示的是大约10个应用程序的两次重新部署。

我不确定为什么GC不能释放分配给旧类的内存。该服务器总共有16GB物理内存,所以我最多可以重新部署所有应用程序20-40次,然后就完成了。应用服务器将达到极限并停止响应任何命令。

因此,如果有人能帮助我了解实际问题是什么,我将非常感激:

  1. 这是Java8的问题吗?(jdk 1.8.0_40-b26)
  2. 这是Wildfly 8.2.1的问题吗?
  3. 或者答案可能是最简单的,即原因在于我的代码库?如果是这样,请指导我实际原因是什么?

与我的代码库相关的一些详细信息

1)与Wildfly一起,我使用了2个独立的HornetQ服务器,每个应用程序都使用至少5个通道,并且每个通道都有至少5个并发消费者。这反过来又导致每个应用程序至少有25个线程,并且总共至少有25*20 = 500个线程。

2)对于所有低级JMS操作,我使用Spring JMS。

2个回答

4
为了实际确定您是否有泄漏(您可能没有泄漏——这可能只是由于合法原因在部署期间加载的合法类),您可以尝试在正确的时间(即在元空间增加之前或之后)获取堆转储。然后,再次获取堆转储。使用MATYourkit等工具对两个堆转储进行比较。两者之间的差异将告诉您正在加载哪些类。
元空间中的泄漏非常罕见,因为您只能加载这么多类,但也可能涉及到某些相当奇特的问题。
让我知道您发现了什么,祝您狩猎愉快!这很有趣。 :-)

我分析了两个堆转储文件(在重新部署约5个构件之前和之后),甚至在计算差异之前就注意到了一些可疑的东西:
  1. 在 http://snag.gy/JGZdf.jpg 之前
  2. 在 http://snag.gy/VqFiN.jpg 之后 下面是它们之间的差异: http://snag.gy/xfDeV.jpg 我发现 char[] 数组增长了很多,(似乎是 String 的内容) 以下是 org.jboss...JavaZipFileSystem 类加载器的内容:http://snag.gy/bbYq7.jpg
因此,我有一个印象,WildFly 只是将所有构件加载到内存中,并且即使在重新部署之后也不会释放它们。这是真的吗?而且这样可以吗?
- Andrei
1
很酷!以下是一些建议:
  1. 您希望在部署之间进行几次转储,以查找单调增加的内存使用模式,并过滤掉随机对象。
  2. 尝试查找您怀疑引起泄漏的对象中的数据(即节点中的值); 这可以引导您的取证工作。
  3. 确保调查您怀疑泄漏的元空间,而不是堆。
  4. 是的,char []类型和其他原语波动很大。 更容易在更高的级别找到泄漏。
  5. 是的,WildFly可能会轻松加载类并不释放它们。 对于JVM,类卸载是可选的。
- entpnerd
你有找到解决办法吗?我也遇到了同样的问题。 - Deibys

1

欢迎来到Stack Overflow!欢迎提供潜在解决方案的链接,但请添加链接周围的上下文,以便其他用户了解它是什么以及为什么存在。始终引用重要链接的最相关部分,以防目标站点无法访问或永久离线。请注意,仅仅是一个指向外部网站的链接可能是为什么和如何删除某些答案的原因之一? - ddb
1
上下文已经存在。这是应用程序中的一个错误,将会被修复。考虑到这个错误很常见,而且这个页面是谷歌搜索结果中排名靠前的,如果删除这个答案,你会给社区带来更多的伤害而不是好处。 - tggm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接