强如 Disruptor 也发生内存溢出?(上)

简介: OutOfMemoryError 问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界、空指针等)来说这类问题是很难定位和解决的。本文以最近碰到的一次线上内存溢出的定位、解决问题的方式展开;希望能对碰到类似问题的同学带来思路和帮助。主要从表现-->排查-->定位-->解决 四个步骤来分析和解决问题。

表象


最近我们生产上的一个应用不断的爆出内存溢出,并且随着业务量的增长出现的频次越来越高。


该程序的业务逻辑非常简单,就是从 Kafka 中将数据消费下来然后批量的做持久化操作。


而现象则是随着 Kafka 的消息越多,出现的异常的频次就越快。由于当时还有其他工作所以只能让运维做重启,并且监控好堆内存以及 GC 情况。


重启大法虽好,可是依然不能根本解决问题。


排查


于是我们想根据运维之前收集到的内存数据、GC 日志尝试判断哪里出现问题。



结果发现老年代的内存使用就算是发生 GC 也一直居高不下,而且随着时间推移也越来越高。


结合 jstat 的日志发现就算是发生了 FGC 老年代也已经回收不了,内存已经到顶。



甚至有几台应用 FGC 达到了上百次,时间也高的可怕。


这说明应用的内存使用肯定是有问题的,有许多赖皮对象始终回收不掉。


定位


由于生产上的内存 dump 文件非常大,达到了几十G。也是由于我们的内存设置太大有关。


所以导致想使用 MAT 分析需要花费大量时间。


因此我们便想是否可以在本地复现,这样就要好定位的多。


为了尽快的复现问题,我将本地应用最大堆内存设置为 150M。


然后在消费 Kafka 那里 Mock 为一个 while 循环一直不断的生成数据。


同时当应用启动之后利用 VisualVM 连上应用实时监控内存、GC 的使用情况。


结果跑了 10 几分钟内存使用并没有什么问题。根据图中可以看出,每产生一次 GC 内存都能有效的回收,所以这样并没有复现问题。



没法复现问题就很难定位了。于是我们 review 代码,发现生产的逻辑和我们用 while 循环 Mock 数据还不太一样。


查看生产的日志发现每次从 Kafka 中取出的都是几百条数据,而我们 Mock 时每次只能产生一条


为了尽可能的模拟生产情况便在服务器上跑着一个生产者程序,一直源源不断的向 Kafka 中发送数据。


果然不出意外只跑了一分多钟内存就顶不住了,观察左图发现 GC 的频次非常高,但是内存的回收却是相形见拙。



同时后台也开始打印内存溢出了,这样便复现出问题。


解决


从目前的表现来看就是内存中有许多对象一直存在强引用关系导致得不到回收。


于是便想看看到底是什么对象占用了这么多的内存,利用 VisualVM 的 HeapDump 功能可以立即 dump 出当前应用的内存情况。



相关文章
|
消息中间件 监控 Java
强如 Disruptor 也发生内存溢出?(下)
OutOfMemoryError 问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界、空指针等)来说这类问题是很难定位和解决的。 本文以最近碰到的一次线上内存溢出的定位、解决问题的方式展开;希望能对碰到类似问题的同学带来思路和帮助。 主要从表现-->排查-->定位-->解决 四个步骤来分析和解决问题。
|
Java
Disruptor 全解析(7):解密内存屏障(Memory Barrier)
原文地址:http://mechanitis.blogspot.com/2011/08/dissecting-disruptor-why-its-so-fast.html​​, 作者是 Trisha Gee, LMAX 公司的一位女工程师。
2538 0
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
360 0
|
20天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
41 1
|
24天前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
28天前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
1月前
|
存储 编译器
数据在内存中的存储
数据在内存中的存储
37 4