提出的问题:server100万人在线,16G内存快被吃光。

玩家进程占用内存偏高

解决方法:

第一步:

erlang:system_info(process_count). 查看进程数目是否正常,是否超过了erlang虚拟机的最大进程数。

第二步:

查看节点的内存瓶颈所在地方

> erlang:memory().

[{total,2099813400},

 {processes,1985444264},

 {processes_used,1985276128},

 {system,114369136},

 {atom,4479545},

 {atom_used,4477777},

 {binary,22756952},

 {code,10486554},

 {ets,47948808}]

显示内存大部分消耗在进程上,由此确定是进程占用了大量内存



第三步:

查看占用内存最高的进程

>spawn(fun()-> etop:start([{output, text}, {interval, 1}, {lines, 20}, {sort, memory}]) end).

(以输出text方式启动etop,其间隔为1秒,输出行数为20行,依照内存排序. 这里spawn一个新进程,目的是输出etop数据时不影响erlang shell 输入.)

第四步:查看占用内存最高的进程状态

>erlang:process_info(pid(0,12571,0)).           

[{current_function,{mod_player,send_msg,2}},

 {initial_call,{erlang,apply,2}},

 {status,waiting},

 {message_queue_len,0},

 {messages,[]},

 {links,[<0.12570.0>]},

 {dictionary,[]},

 {trap_exit,false},

 {error_handler,error_handler},

 {priority,normal},

 {group_leader,<0.46.0>},

 {total_heap_size,12538050},

 {heap_size,12538050},

 {stack_size,10122096},

 {reductions,3795950},

 {garbage_collection,[{min_bin_vheap_size,46368},

                      {min_heap_size,233},

                      {fullsweep_after,65535},

                      {minor_gcs,0}]},

 {suspending,[]}]



当中” {total_heap_size,12538050},”表示占用内存为 12358050 words(32位系统word size为4,64位系统word size为8, 能够通过erlang:system_info(wordsize) 查看),在64位系统下将近100M, 太夸张了!




第五步:

手动gc回收,希望问题能够解决

> erlang:garbage_collect(pid(0,12571,0)).

true

再次查看进程内存,发现没有不论什么变化!gc没有回收到不论什么资源,因此消耗的内存还在发挥作用,没有回收!



第六步:

不要怀疑系统,首先要怀疑自己的代码

认真观察代码,其大致结构例如以下:

send_msg(Socket, Pid) ->

   try

       receive

           {send, Bin} ->

               ...

           {inet_reply, _Sock, Result} ->

               ...

   catch

       _:_->

           send_msg(Sock,Pid)

   end.

其目的是循环等待数据,然后进行发送,其使用了try...catch捕获异常.

这段代码不是尾递归! try...catch会在stack中保存对应的信息,异常捕获须要放置在函数内部,所以send_msg最后调用的是try...catch。而不是自身,所以不是尾递归。

能够通过代码得到验证:

 cat test.erl

-module(test).

-compile([export_all]).





t1() ->

   Pid = spawn(fun()-> do_t1() end),

   send_msg(Pid, 100000).



t2() ->

   Pid = spawn(fun()-> do_t2() end),

   send_msg(Pid, 100000).



send_msg(_Pid, 0) ->

   ok;

send_msg(Pid, N) ->

   Pid !<<2:(N)>>,

   timer:sleep(200),

   send_msg(Pid, N-1).



do_t1() ->

   erlang:garbage_collect(self()),

   Result =erlang:process_info(self(), [memory, garbage_collection]),

   io:format("~w~n", [Result]),

   io:format("backtrace:~w~n~n",[erlang:process_display(self(), backtrace)]),

   try

     receive

         _->

             do_t1()

     end

   catch

     _:_ ->

         do_t1()

   end.



do_t2() ->

   erlang:garbage_collect(self()),

   Result =erlang:process_info(self(), [memory, garbage_collection]),

   io:format("~w~n", [Result]),

   io:format("backtrace:~w~n~n",[erlang:process_display(self(), backtrace)]),

   receive

     _ ->

         do_t2()

   end.



版本号1:erlctest.erl && erl -eval "test:t1()"

版本号2:erlctest.erl && erl -eval "test:t2()"

你会看到版本号1代码的调用堆栈在不断增长,内存也在增长, 而版本号2函数调用地址保持不变,内存也没有发生变化!



总结:

1,server编程中,循环一定确保为尾递归

2,尽量使用OTP,假设使用gen_server更换手写loop,将避免这个问题

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Erlangserver紧内存优化解决方案的更多相关文章

  1. Android性能优化:手把手带你全面了解 内存泄露 & 解决方案

    . 简介 即 ML (Memory Leak)指 程序在申请内存后,当该内存不需再使用 但 却无法被释放 & 归还给 程序的现象2. 对应用程序的影响 容易使得应用程序发生内存溢出,即 OOM ...

  2. Android性能优化:手把手带你全面实现内存优化

      前言 在 Android开发中,性能优化策略十分重要 本文主要讲解性能优化中的内存优化,希望你们会喜欢 目录   1. 定义 优化处理 应用程序的内存使用.空间占用 2. 作用 避免因不正确使用内 ...

  3. [转]探索 Android 内存优化方法

    前言 这篇文章的内容是我回顾和再学习 Android 内存优化的过程中整理出来的,整理的目的是让我自己对 Android 内存优化相关知识的认识更全面一些,分享的目的是希望大家也能从这些知识中得到一些 ...

  4. JavaScript内存优化

    JavaScript内存优化 相对C/C++ 而言,我们所用的JavaScript 在内存这一方面的处理已经让我们在开发中更注重业务逻辑的编写.但是随着业务的不断复杂化,单页面应用.移动HTML5 应 ...

  5. Unity3D 游戏开发之内存优化

    项目的性能优化主要围绕CPU.GPU和内存三大方面进行. 无论是游戏还是VR应用,内存管理都是其研发阶段的重中之重. 然而,在我们测评过的大量项目中,90%以上的项目都存在不同程度的内存使用问题.就目 ...

  6. SQLServer2014内存优化表评测

    SQLServer2014内存优化表评测 分类: SQL内存表2014-06-20 11:49 1619人阅读 评论(11) 收藏 举报 目录(?)[-] SQLServer2014的使用基本要求 内 ...

  7. 【MDCC技术大咖秀】Android内存优化之OOM

    大神分析的很全面,所以就转过来保存一份,转自:http://www.csdn.net/article/2015-09-18/2825737/1 以下为正文: Android的内存优化是性能优化中很重要 ...

  8. Android内存优化之OOM

    内容大多都是和OOM有关的实践总结概要.理解错误或是偏差的地方,还请多包涵指正,谢谢!本人Q:1524447071 (一)Android的内存管理机制 Google在Android的官网上有这样一篇文 ...

  9. 【腾讯Bugly干货分享】Android内存优化总结&实践

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/2MsEAR9pQfMr1Sfs7cPdWQ 导语 智 ...

随机推荐

  1. C++数据结构之二叉树

    之前打算编算法类的程序,但是搞了几次英雄会后,觉得作为一个还在学习阶段的学生,实在是太浪费时间了,并不是没意义,而是我的基础还不牢固啊.所以转变了思路,这个学期打算分别用C++.Python.Java ...

  2. poj 3263 Tallest Cow

    一个压了很久的题目,确实很难想,看了别人的做法后总算明白了. 首先要明白一点,因为题目说明了不会有矛盾,所以题目给出来的区间是不能相交的,否则是矛盾的.(原因自己想) 然后既然区间只能是包含的,就很明 ...

  3. SQL SERVER 2008- 字符串函数

    /* 1,ASCII返回字符表达式中最左侧字符的ASCII代码值 仅返回首字母的ASCII码值 parameter char或varchar returns integer */ SELECT ASC ...

  4. asp.net2.0安全性(2)--用户个性化设置(2)--转载来自车老师

    上一篇我们用Profile.age等方式可以读取用户的年龄和其它的信息,但有的时候我们要查询显示所有用户的信息,但asp.net没有提供查询所有用户信息的功能,我们只能对现有的用户逐一查询其Profi ...

  5. 设计模式6:Composite

    Entry.java: package gendwang.cisco.com; public abstract class Entry { private int height = 0; privat ...

  6. Swift - 使用UIImagePickerController从相册选择照片并展示

    1,UIImagePickerController介绍 (1)选择相册中的图片或者拍照,都是通过UIImagePickerController控制器实例化一个对象,然后通过self.presentVi ...

  7. 算法设计与分析——多边形游戏(DP)

    1.问题描述:   给定N个顶点的多边形,每个顶点标有一个整数,每条边上标有+(加)或是×(乘)号,并且N条边按照顺时针依次编号为1~N.下图给出了一个N=4个顶点的多边形. 游戏规则 :(1) 首先 ...

  8. uva 10603

    紫皮书的例题 照着敲了一遍,非原创 大题思路主要是三杯水,而水的总数是知道的,相当于知道第一第二杯水的体积,第三杯水的体积也就确定了. 用第一第二杯水的体积来标记数组是否遍历过 优先队列来找移动体积最 ...

  9. hdu 4707 搜索 目前做的最水的搜索

    直接深搜  ,水啊 #include<cstdio> #include<cstring> #include<algorithm> using namespace s ...

  10. Opencv实现图像的灰度处理,二值化,阀值选择

    前几天接触了图像的处理,发现用OPencv处理确实比較方便.毕竟是非常多东西都封装好的.可是要研究里面的东西,还是比較麻烦的,首先,你得知道图片处理的一些知识,比方腐蚀,膨胀,仿射,透射等,还有非常多 ...