【问题标题】:Direct buffer memory OutOfMemoryError after updating to wildfly 18更新到wildfly 18后直接缓冲内存OutOfMemoryError
【发布时间】:2021-12-14 14:01:25
【问题描述】:

在将环境从 Wildfly 13 更新到 Wildfly 18.0.1 后,我们经历了一个

A channel event listener threw an exception: java.lang.OutOfMemoryError: Direct buffer memory
at java.base/java.nio.Bits.reserveMemory(Bits.java:175)
at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:118)
at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:317)
at org.jboss.xnio@3.7.3.Final//org.xnio.BufferAllocator$2.allocate(BufferAllocator.java:57)
at org.jboss.xnio@3.7.3.Final//org.xnio.BufferAllocator$2.allocate(BufferAllocator.java:55)
at org.jboss.xnio@3.7.3.Final//org.xnio.ByteBufferSlicePool.allocateSlices(ByteBufferSlicePool.java:162)
at org.jboss.xnio@3.7.3.Final//org.xnio.ByteBufferSlicePool.allocate(ByteBufferSlicePool.java:149)
at io.undertow.core@2.0.27.Final//io.undertow.server.XnioByteBufferPool.allocate(XnioByteBufferPool.java:53)
at io.undertow.core@2.0.27.Final//io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:147)
at io.undertow.core@2.0.27.Final//io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:136)
at io.undertow.core@2.0.27.Final//io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:59)
at org.jboss.xnio@3.7.3.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.jboss.xnio@3.7.3.Final//org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.jboss.xnio.nio@3.7.3.Final//org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
at org.jboss.xnio.nio@3.7.3.Final//org.xnio.nio.WorkerThread.run(WorkerThread.java:591)

应用程序端没有任何改变。我查看了缓冲池,似乎有些资源没有被释放。我触发了几次手动 GC,但几乎没有任何反应。 (正常运行时间 2 小时)

在旧配置之前它看起来像这样(正常运行时间>250h):

现在我做了很多研究,我能找到的最接近的就是这个post 在 SO 上。然而,这是与 websockets 结合使用的,但没有 没有 websockets 正在使用中。 我阅读了几篇(好)文章(1,2,3,4,5,6)并观看了video关于该主题的这篇文章。 我尝试了以下事情但没有任何效果:

  1. OutOfMemoryError 发生在 5GB,因为堆是 5GB => 我将 MaxDirectMemorySize 减小到 512m,然后减小到 64m,但是 OOM 发生得更快
  2. 我设置-Djdk.nio.maxCachedBufferSize=262144
  3. 我检查了 IO 工作人员的数量:96 (6cpus*16),这似乎是合理的。系统通常具有短寿命线程(最大池大小为 13)。所以我猜这不可能是工人的数量
  4. 我切换回 ParallelGC,因为这是 Java8 中的默认设置。现在在进行手动 GC 时,至少会释放 10MB。对于 GC1,什么都没有发生。但是两个 GC 仍然无法清理。
  5. 为了确定,我从 wildfly 配置中删除了 &lt;websockets&gt;
  6. 我尝试在本地模拟它但失败了。
  7. 我使用 eclipseMAT 和 JXRay 分析了堆,但它只是指向一些内部的 Wildfly 类。
  8. 我将 Java 恢复到版本 8,但系统仍然显示相同的行为,因此 Wildfly 是最有可能的嫌疑人。

在 eclipseMAT 中也可以找到这 1544 个对象。他们都得到了相同的大小。

唯一起作用的是完全停用 Wildfly 中的字节缓冲区。

/subsystem=io/buffer-pool=default:write-attribute(name=direct-buffers,value=false)

但是从我读到的内容来看,这有性能缺陷?

那么有人知道问题出在哪里吗?有关其他设置/调整的任何提示?或者是否存在与此相关的已知 Wildfly 或 JVM 错误?

更新 1:关于 IO 线程 - 也许这个概念对我来说不是 100% 清楚。因为有ioThreads 还有线程和线程池。

从定义可以认为每个工作线程创建ioThreads 的数量(在我的情况下为12)?但就我而言,线程/工作人员的数量似乎仍然很低......

更新 2: 我降级了 java,它仍然显示相同的行为。因此,我怀疑 Wildfly 是问题的原因。

【问题讨论】:

  • 能否回滚其中一个版本升级,看看能否减少“嫌疑人池”?
  • @Gus 这也是我的一个想法。我会尝试并报告。
  • 这里有来自旧版 WildFly 的讨论stackoverflow.com/questions/63519501/…;可能是相关的,因为看起来他们没有修复“错误”,只是建议更改配置(减少 io 工作线程数)。
  • 在 Java 中创建的 DirectByteBuffers 在 Buffer 对象变得无法访问时(使用 Cleaners)清理其本机内存。在 OOME 发生之前,这种情况不会发生,这似乎意味着资源泄漏:某些东西正在保留 Buffer 对象,这意味着永远无法清理支持的本机内存。 FWIW,这对我来说看起来不像 JVM 错误。更有可能你必须做一些事情来显式释放资源(比如在某处调用 close(),或者删除对间接引用缓冲区的东西的全局引用)。
  • FWIW,取决于您如何执行它们,以及使用的 GC,手动 GC 可能没有效果,因为 GC 不会“看到”附加到缓冲区的本机内存。通常您必须首先增加 Java 堆的压力(例如,通过在循环中分配大型数组),然后然后执行手动 GC 以触发清理。

标签: java out-of-memory wildfly java-11 undertow


【解决方案1】:

可能是 Xnio 的问题。看这个问题https://issues.redhat.com/browse/JBEAP-728

【讨论】:

  • 我浏览了所有 Wildfly 更改日志,但没有找到任何相关内容。我没想到还要检查 jboss EAP。但是,该错误来自 2015 年,并未在 Wildfly 13.0.1(2018 年 5 月 31 日)中发生。但是现在在 wildfly 18.0.1(从 2019 年 11 月 14 日开始)中它是否突然出现?
【解决方案2】:

经过大量的分析、剖析等,我得出以下结论:

  • OOM的原因是18.0.1版本的wildfly引起的。它也存在于 19.1.0 中(未测试 20 或 21)
  • -XX:MaxDirectMemorySize 设置为512m 或更低的值时,我能够相当快地触发OOM。我想很多人都没有遇到过这个问题,因为默认情况下这个值等于 Xmx 值,这个值可能很大。使用我们应用程序的 ReST API 时会出现问题
  • 正如 Evgeny 指出的 XNIO is a high potential candidate,因为在分析时它缩小到(或接近)该区域...
  • 我没有时间进一步调查,所以我尝试了 wildfly 22,它在那里工作。此版本使用最新的 xnio 包 (3.8.4)
  • WF 22 中的 DirectMemory 仍然很低。大约为 10mb。可以看到计数上升和下降,这是以前没有的情况

所以最终修复是更新到 wildfly 版本 22.0.1(或更高版本)

【讨论】:

    猜你喜欢
    • 2020-12-10
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2017-02-20
    • 2020-04-25
    • 1970-01-01
    • 2017-11-21
    相关资源
    最近更新 更多