一次由Erlang垃圾回收导致的内存泄漏

文章讲述了作者在排查Erlang服务因内存泄漏导致OOM的过程中,发现问题是由于垃圾回收机制导致的。通过etop定位到一个每月运行一次的统计线程和MySQL线程占据了大部分内存。经过代码分析和远程shell验证,确认为Erlang的垃圾回收策略导致内存未被及时释放。通过深入理解Erlang垃圾回收机制,提出了三种优化方案,最终选择通过调整SQL语句避免一次性加载大量数据,成功解决了内存泄漏问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近有一个erlang的服务因为oom被kernel kill掉了, 由于从监控来说这个服务确实是内存不断增长。所以这个服务应该在哪里有内存泄漏才对。于是我又一次开始定位这个问题。

定位到底哪个进程占用了最多的内存

由于在另一个节点有一个没有crash,但是内存仍旧很高的节点,所以这个问题处理起来很简单。erlang提供了完整的运行时系统debug环境。这里我们用etop,根据memory排序,查看具体哪个线程占用了最多的内存。

erl -sname etopnode -hidden -s etop -output text -sort memory \ 
-lines 20 -tracing false -node 'node_name@host_name' -setcookie your_cookie

在有erlang的机器上执行这个命令,即可连接到具体的节点,通过etop得到所有线程信息,按内存排序,显示最多内存的20条线程。etop记录里的memory使用KB做单位。

在这次问题里,我定位到的内容包括

  1. 最大内存占用来自一个每月跑一次的统计线程。该线程为一个gen_server,用于生成一个信用分排行榜。这个线程占用超过50%内存。大概900M左右的内存。
  2. 第二大内存占用者是mysql线程。该线程占用超过25%内存。大概500M内存

进一步代码分析

已经定位到了75%以上内存占用了。肯定是先分析第一内存占用的线程的具体逻辑了。

  1. 启动之后,就定时触发一个检查请求
  2. 该请求检查当前时间是否为每月月初。
  3. 如果是,获取一个分布式锁。
  4. 如果分布式锁获取
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值