随着项目越来越依赖Erlang,碰到的问题也随之增加。前段时间线上系统碰到内存高消耗问题,记录一下troubleshooting的分析过程。线上系统用的是Erlang R16B02版本。

问题描述

有几台线上系统,运行一段时间,内存飙升。系统模型很简单,有网络连接,pool中找新的process进行处理。top命令观察,发现内存都被Erlang进程给吃完了,netstat命令查看网络连接数,才区区几K。问题应该是Erlang内存泄漏了。

分析方法

Erlang系统有个好处,可以直接进入线上系统,在生产现场分析问题。我们系统是通过Rebar管理的,可以用不同方法进入线上系统。

本机登录

可以直接登录到线上机器,然后通过以下命令attach到Erlang系统里面

$ cd /path/to/project
$ rel/xxx/bin/xxx attach
(node@host)>

通过remote shell

获取Erlang系统的cookie

$ ps -ef |grep beam  %%找到参数 --setcookie

新开一个shell,使用同样的cookie,不同的nodename

$ erl --setcookie cookiename -name test@127.0.0.1

用start remote shell进入系统

Erlang R16B02 (erts-5.10.3) [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V5.10.3  (abort with ^G)
(test1@127.0.0.1)1> net_adm:ping('node@127.0.0.1').
pong
(test1@127.0.0.1)2> nodes().
['node@127.0.0.1']
(test1@127.0.0.1)3>
User switch command
--> h
c [nn] - connect to job
i [nn] - interrupt job
k [nn] - kill job
j - list all jobs
s [shell] - start local shell
r [node [shell]] - start remote shell
q - quit erlang
? | h - this message
--> r 'node@127.0.0.1'
--> j
1 {shell,start,[init]}
2* {'node@127.0.0.1',shell,start,[]}
--> c 2

分析流程

Erlang有很多工具,可以分析系统信息,比如appmonwebtool。但是系统内存严重不足,已经没有办法启动这些工具了,幸好还有Erlang shell。

Erlang shell自带了很多有用的命令,可以用help()方法查看

> help().

Erlang系统内存消耗情况

top结果显示,是内存问题,所以第一步可以先看看Erlang的系统内存消耗情况

> erlang:memory().

memory()可以看到Erlang emulator分配的内存,有总的内存,atom消耗的内存,process消耗的内存等等。

Erlang process创建数量

线上系统发现主要内存消耗都在process上面,接下来要分析,是process内存泄漏了,还是process创建数量太多导致。

> erlang:system_info(process_limit).  %%查看系统最多能创建多少process
> erlang:system_info(process_count). %%当前系统创建了多少process

system_info()返回当前系统的一些信息,比如系统process,port的数量。执行上面命令,大吃一惊,只有2,3k的网络连接,结果Erlang process已经有10多w了。系统process创建了,但是因为代码或者其它原因,堆积没有释放。

查看单个process的信息

既然是因为process因为某种原因堆积了,只能从process里找原因了

先要获取堆积process的pid

> i().  %%返回system信息
> i(0,61,886). %% (0,61,886)是pid

看到有很多process hang在那里,查看具体pid信息,发现message_queue有几条消息没有被处理。下面就用到强大的erlang:process_info()方法,它可以获取进程相当丰富的信息。

> erlang:process_info(pid(0,61,886), current_stacktrace).
> rp(erlang:process_info(pid(0,61,886), backtrace)).

查看进程的backtrace时,发现下面的信息

0x00007fbd6f18dbf8 Return addr 0x00007fbff201aa00 (gen_event:rpc/2 + 96)
y(0) #Ref<0.0.2014.142287>
y(1) infinity
y(2) {sync_notify,{log,{lager_msg,[], ..........}}
y(3) <0.61.886>
y(4) <0.89.0>
y(5) []

process在处理Erlang第三方的日志库lager时,hang住了。

问题原因

查看lager的文档,发现以下信息

Prior to lager 2.0, the gen_event at the core of lager operated purely in synchronous mode. Asynchronous mode is faster, but has no protection against message queue overload. In lager 2.0, the gen_event takes a hybrid approach. it polls its own mailbox size and toggles the messaging between synchronous and asynchronous depending on mailbox size.

{async_threshold, 20}, {async_threshold_window, 5}

This will use async messaging until the mailbox exceeds 20 messages, at which point synchronous messaging will be used, and switch back to asynchronous, when size reduces to 20 - 5 = 15.

If you wish to disable this behaviour, simply set it to 'undefined'. It defaults to a low number to prevent the mailbox growing rapidly beyond the limit and causing problems. In general, lager should process messages as fast as they come in, so getting 20 behind should be relatively exceptional anyway.

原来lager有个配置项,配置message未处理的数量,如果message堆积数超出,则会用 同步 方式处理!

当前系统打开了debug log,洪水般的log把系统给冲垮了。

老外也碰到类似问题,这个thread给我们的分析带来很多帮助,感谢一下。

总结

Erlang提供了丰富的工具,可以在线进入系统,现场分析问题,这个非常有助于高效、快速的定位问题。同时,强大的Erlang OTP让系统有更稳定的保证。我们还会继续挖掘Erlang,期待有更多的实践分享。

关于作者

微博@liaolinbo,云巴首席工程师。曾于Oracle工作。

Erlang 内存泄漏分析的更多相关文章

  1. Java内存泄漏分析与解决方案

    Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历 ...

  2. Android内存泄漏分析及调试

    尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/13017999 此文承接我的另一篇文章:Android进程的内存管理分析 首先 ...

  3. Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  4. Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析

    原文地址:http://www.javatang.com 症状及解决方案 下面列出几种常见的症状即对应的解决方案: CPU占用率很高,响应很慢 按照<Java内存泄漏分析系列之一:使用jstac ...

  5. Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析

    原文地址:http://www.javatang.com 一个典型的thread dump文件主要由一下几个部分组成: 上图将JVM上的线程堆栈信息和线程信息做了详细的拆解. 第一部分:Full th ...

  6. Javascript的内存泄漏分析

    作为程序员(更高大尚的称谓:研软件研发)的我们,无论是用Javascript,还是.net, java语言,肯定都遇到过内存泄漏的问题.只不过他们都有GC机制来帮助程序员完成内存回收的事情,如果你是C ...

  7. Android内存泄漏分析实战

    内存泄漏简单介绍 java能够保证当没有引用指向对象的时候,对象会被垃圾回收器回收.与c语言自己申请的内存自己释放相比,java程序猿轻松了非常多.可是并不代表java程序猿不用操心内存泄漏.当jav ...

  8. (转)Android内存泄漏分析及调试

      http://blog.csdn.net/gemmem/article/details/13017999 此文承接我的另一篇文章:Android进程的内存管理分析  首先了解一下dalvik的Ga ...

  9. 使用Eclipse Memory Analyzer进行内存泄漏分析三部曲

    源地址:http://seanhe.iteye.com/blog/898277 一.准备工作  分析较大的dump文件(根据我自己的经验2G以上的dump文件就需要使用以下介绍的方法,不然mat会出现 ...

随机推荐

  1. 明天去FDUSC报道了,GOD BLESS ALL OF US

    @lrb @tellmewtf @proverbs

  2. 搭建WebRtc环境

    0.前言 这次的需求,准备做的是一个类似与QQ视频一样的点对点视频聊天.这几天了解了一些知识后,决定使用HTML5新支持的WebRtc来作为视频通讯.客户端使用支持HTML5浏览器即可.服务器段需要提 ...

  3. HANA Studio打开系统显示Secure storage is locked

    之前一直用着好好的,今天打开HANA Studio突然发现一个系统都不在了: 提示:‘Secure storage is locked’ 我点旁边的Unlocked没有任何反应,右键也没有功能了.如下 ...

  4. ORM:ODB安装使用过程

      1.下载odb-2.4.0-i686-windows,是cpp和sql文件生成工具,已经编译好了,如果下odb-2.4.0估计是未编译好的这个项目:   2.将...\odb-2.4.0-i686 ...

  5. 如何克隆kvm虚拟机

    关于如何使用kvm虚拟化技术创建虚拟机,这里有一系列博客讲的已经非常清楚了,这里不再赘述,不过其中有些小坑可能需要大家注意: 0. 写在创建虚拟机之前(即教程的系列三之前) 1. 确认防火墙是否关闭, ...

  6. cocos2d-x中使用可加密Sqlite存储玩家数据

    手机游戏当中的数据存储是一个重要的课题.cocos2d-x发展到现在的版本2.1.4,已经直接实现了对sqlite的支持(extensions/LocalStorage),这对我们一般的数据存储已经够 ...

  7. Gulp.js - 简单、直观的自动化项目构建工具

    Gulp.js 是一个简单.直观的构建系统.崇尚代码优于配置,使复杂的任务更好管理.通过结合 NodeJS 的数据流的能力,你能够快速构建.通过简单的 API 接口,只需几步就能搭建起自己的自动化项目 ...

  8. iOS-UITableView-处理cell上按钮事件(弹出警示框,页面跳转等)

    一. 目的: 实现UITableViewCell上按钮点击事件可以进行页面跳转. 二. 实现方法: 1. 用协议的方式的实现. 2. 需要自定义UITableViewCell. 三. 代码部分. ce ...

  9. js 实现各种排序

    一 冒泡排序 一万个随机数排序五次执行时间分别为 362 389 361 372 408 毫秒 var arr=[]; for(var j=0;j<10000;j++){ arr.push(Ma ...

  10. 希望早几年知道的5个Unix命令

    原文: http://spin.atomicobject.com/2013/09/09/5-unix-commands/ 希望早几年知道的5个Unix命令 使用*nix系统已经有一段时间了.但是还是有 ...