主頁 > 知識庫 > Erlang項目內存泄漏分析方法

Erlang項目內存泄漏分析方法

熱門標簽:地圖標注如何弄全套標 武漢AI電銷機器人 電銷機器人 深圳 外呼系統會封嗎 萬利達綜合醫(yī)院地圖標注點 實體店地圖標注怎么標 股票配資電銷機器人 南京電銷外呼系統哪家好 在電子版地圖標注要收費嗎

隨著項目越來越依賴Erlang,碰到的問題也隨之增加。前段時間線上系統碰到內存高消耗問題,記錄一下troubleshooting的分析過程。線上系統用的是Erlang R16B02版本。

問題描述

有幾臺線上系統,運行一段時間,內存飆升。系統模型很簡單,有網絡連接,pool中找新的process進行處理。top命令觀察,發(fā)現內存都被Erlang進程給吃完了,netstat命令查看網絡連接數,才區(qū)區(qū)幾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有很多工具,可以分析系統信息,比如appmon,webtool。但是系統內存嚴重不足,已經沒有辦法啟動這些工具了,幸好還有Erlang shell。

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

復制代碼 代碼如下:

> help().

Erlang系統內存消耗情況

top結果顯示,是內存問題,所以第一步可以先看看Erlang的系統內存消耗情況

復制代碼 代碼如下:

> erlang:memory().

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

Erlang process創(chuàng)建數量

線上系統發(fā)現主要內存消耗都在process上面,接下來要分析,是process內存泄漏了,還是process創(chuàng)建數量太多導致。

復制代碼 代碼如下:

> erlang:system_info(process_limit).  %%查看系統最多能創(chuàng)建多少process
> erlang:system_info(process_count).  %%當前系統創(chuàng)建了多少process

system_info()返回當前系統的一些信息,比如系統process,port的數量。執(zhí)行上面命令,大吃一驚,只有2,3k的網絡連接,結果Erlang process已經有10多w了。系統process創(chuàng)建了,但是因為代碼或者其它原因,堆積沒有釋放。

查看單個process的信息

既然是因為process因為某種原因堆積了,只能從process里找原因了

先要獲取堆積process的pid

復制代碼 代碼如下:

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

看到有很多process hang在那里,查看具體pid信息,發(fā)現message_queue有幾條消息沒有被處理。下面就用到強大的erlang:process_info()方法,它可以獲取進程相當豐富的信息。
復制代碼 代碼如下:

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

查看進程的backtrace時,發(fā)現下面的信息
復制代碼 代碼如下:

0x00007fbd6f18dbf8 Return addr 0x00007fbff201aa00 (gen_event:rpc/2 + 96)
y(0)     #Ref0.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的文檔,發(fā)現以下信息

復制代碼 代碼如下:

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讓系統有更穩(wěn)定的保證。我們還會繼續(xù)挖掘Erlang,期待有更多的實踐分享。

標簽:濟寧 臺州 泰安 廣東 安徽 汕頭 濟源 武威

巨人網絡通訊聲明:本文標題《Erlang項目內存泄漏分析方法》,本文關鍵詞  Erlang,項目,內存,泄漏,分析,;如發(fā)現本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Erlang項目內存泄漏分析方法》相關的同類信息!
  • 本頁收集關于Erlang項目內存泄漏分析方法的相關信息資訊供網民參考!
  • 推薦文章