Axon 4.7.6中EmbeddedEventStore.trimCache()内存泄漏问题咨询
Axon框架4.7.6版本EmbeddedEventStore.EventProducer内存泄漏问题修复方案
我们在Axon框架4.7.6版本中发现,EmbeddedEventStore.EventProducer类的trimCache()方法存在内存泄漏缺陷,在高负载场景下会引发OutOfMemoryError。
根因分析
该方法的引用管理逻辑存在严重问题,原代码实现如下:
private void trimCache() { Node last = oldest; while (newest != null && last != null && newest.index - last.index >= cachedEvents) { last = last.next; } oldest = last; }
问题具体表现为:
- 引用链未断开:方法仅更新了
oldest指针的指向,但没有切断被移除节点之间的引用连接; - GC无法回收:被剔除的节点仍然可以通过原始的链表引用链被访问到,导致垃圾回收器无法回收这些对象,最终造成内存堆积。
解决方案与修复思路
要解决这个问题,核心是彻底切断被移除节点的所有可达强引用,让GC能够正常回收这些对象。以下是修复后的代码实现:
private void trimCache() { Node currentOldest = oldest; // 先定位到新的oldest节点位置,逻辑与原代码一致 Node newOldest = oldest; while (newest != null && newOldest != null && newest.index - newOldest.index >= cachedEvents) { newOldest = newOldest.next; } // 遍历并断开所有要被移除节点的引用链 Node temp = currentOldest; while (temp != null && temp != newOldest) { Node nextNode = temp.next; temp.next = null; // 切断当前节点与下一个节点的引用 temp = nextNode; } // 更新oldest指针为新的起始节点 oldest = newOldest; }
修复思路说明
- 定位新的缓存起始节点:保留原逻辑中寻找
newOldest的部分,确保缓存的有效范围符合预期; - 切断废弃节点的引用链:遍历原
oldest到newOldest之间的所有节点,将每个节点的next引用置为null,彻底消除这些节点之间的连接,同时也避免它们持有后续有效节点的引用; - 更新缓存起始指针:最后将
oldest指向newOldest,完成缓存的修剪操作。
通过这种方式,所有被从缓存中移除的节点不再存在任何可达的强引用,垃圾回收器可以正常回收这些对象,从根源上解决内存泄漏问题。
内容的提问来源于stack exchange,提问作者zly
相关产品推荐
相关产品推荐

