Erlangserver紧内存优化解决方案
提出的问题: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紧内存优化解决方案的更多相关文章
- Android性能优化:手把手带你全面了解 内存泄露 & 解决方案
. 简介 即 ML (Memory Leak)指 程序在申请内存后,当该内存不需再使用 但 却无法被释放 & 归还给 程序的现象2. 对应用程序的影响 容易使得应用程序发生内存溢出,即 OOM ...
- Android性能优化:手把手带你全面实现内存优化
前言 在 Android开发中,性能优化策略十分重要 本文主要讲解性能优化中的内存优化,希望你们会喜欢 目录 1. 定义 优化处理 应用程序的内存使用.空间占用 2. 作用 避免因不正确使用内 ...
- [转]探索 Android 内存优化方法
前言 这篇文章的内容是我回顾和再学习 Android 内存优化的过程中整理出来的,整理的目的是让我自己对 Android 内存优化相关知识的认识更全面一些,分享的目的是希望大家也能从这些知识中得到一些 ...
- JavaScript内存优化
JavaScript内存优化 相对C/C++ 而言,我们所用的JavaScript 在内存这一方面的处理已经让我们在开发中更注重业务逻辑的编写.但是随着业务的不断复杂化,单页面应用.移动HTML5 应 ...
- Unity3D 游戏开发之内存优化
项目的性能优化主要围绕CPU.GPU和内存三大方面进行. 无论是游戏还是VR应用,内存管理都是其研发阶段的重中之重. 然而,在我们测评过的大量项目中,90%以上的项目都存在不同程度的内存使用问题.就目 ...
- SQLServer2014内存优化表评测
SQLServer2014内存优化表评测 分类: SQL内存表2014-06-20 11:49 1619人阅读 评论(11) 收藏 举报 目录(?)[-] SQLServer2014的使用基本要求 内 ...
- 【MDCC技术大咖秀】Android内存优化之OOM
大神分析的很全面,所以就转过来保存一份,转自:http://www.csdn.net/article/2015-09-18/2825737/1 以下为正文: Android的内存优化是性能优化中很重要 ...
- Android内存优化之OOM
内容大多都是和OOM有关的实践总结概要.理解错误或是偏差的地方,还请多包涵指正,谢谢!本人Q:1524447071 (一)Android的内存管理机制 Google在Android的官网上有这样一篇文 ...
- 【腾讯Bugly干货分享】Android内存优化总结&实践
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/2MsEAR9pQfMr1Sfs7cPdWQ 导语 智 ...
随机推荐
- Android Studio经常使用操作技巧(不断更新)
这段时间一直在用Android Studio做一些Demo的开发.一開始从Eclipse中转向这个开发工具,各种不适应,希望此博文能够一直更新.还有网友能够分享出自己方便更好更快开发的一些技巧. 首先 ...
- MSSQL - 因为数据库正在使用,所以无法获得对数据库的独占访问权。
关于“因为数据库正在使用,所以无法获得对数据库的独占访问权”的最终解决方案 今天在使用SQL Server2005对某个数据库进行还原操作的时候,出现了如上问题,“因为数据库正在使用,所以无法获得 ...
- java按值传递理解(转)
ava没有引用传递只有按值传递,没有引用传递只有按值传递,值传递. 通过下面代码解释: 1 public class Test { 2 public static void main(String[] ...
- 一种根据URL参数条件动态生成URL的方法
最近做了一个产品列表页类似于搜索列表页, 功能比较简单,比搜索页复杂的逻辑在于,生成各个查询条件的URL.我们的链接如下: http://xxx.xxx.xxx/product/list.html?s ...
- 一步一步实现FormsAuthentic验证登录
本文不讲原理,只讲用法,原理性的东西网上特别多,不过还是会对一些要用到的东西进行解释,不深入讲原理.本文中用的是Vs2012 .net mvc 4.0.原理看这篇文章,看完这个文章绝对受益匪浅. ...
- Delphi 能不能从Ring 3进入Ring 0
我发现了一篇发表在1999.11.29 b13版的 <令win32应用程序跳入系统层>东南大学 卢威 luwei@126.com 是用vc++嵌汇编做的, ...
- 与众不同 windows phone (4) - Launcher(启动器)
原文:与众不同 windows phone (4) - Launcher(启动器) [索引页][源码下载] 与众不同 windows phone (4) - Launcher(启动器) 作者:weba ...
- getResource(String name)用法及源码分析
Project获取资源需要一个启点,加载资源的动作是由ClassLoader来完成的.Class对象和当前线程对象可以找到当前加载资源的ClassLoader,通过ClassLoader的getRes ...
- POJ 2632 Crashing Robots(较为繁琐的模拟)
题目链接:http://poj.org/problem?id=2632 题目大意:题意简单,N个机器人在一个A*B的网格上运动,告诉你机器人的起始位置和对它的具体操作,输出结果: 1.Robot i ...
- libuv 初窥--转
过年了,人都走光了,结果一个人活也干不了.所以我便想找点东西玩玩. 今天想试一下 libev 写点代码.原本在我那台 ubuntu 机器上一点问题都没有,可在 windows 机上用 mingw 编译 ...