Erlang:内存使用数据的差异

时间:2011-07-28 14:59:47

标签: erlang

当我运行WebSocket测试时,我发现了以下有趣的内存使用结果:

服务器声明,没有连接

[{total,573263528},
 {processes,17375688},
 {processes_used,17360240},
 {system,555887840},
 {atom,472297},
 {atom_used,451576},
 {binary,28944},
 {code,3774097},
 {ets,271016}]
44 processes,
System:705M, 
Erlang Residence:519M

100K连接

[{total,762564512},
 {processes,130105104},
 {processes_used,130089656},
 {system,632459408},
 {atom,476337},
 {atom_used,456484},
 {binary,50160},
 {code,3925064},
 {ets,7589160}]
100044 processes,
System: 1814M, 
Erlang Residence: 950M

200K连接

(重启服务器并从0连接创建,不从案例2继续)

[{total,952040232},
 {processes,243161192},
 {processes_used,243139984},
 {system,708879040},
 {atom,476337},
 {atom_used,456484},
 {binary,70856},
 {code,3925064},
 {ets,14904760}]
200044 processes,
System:3383M, 
Erlang: 1837M

带有“System:”和“Erlang:”的数字是htop提供的,其他是从erlang shell输出的memory()调用。请查看总和和二郎住宿记忆。当没有连接时,这两个大致相同,有100K连接,驻留内存比总数大一点,有200K连接,驻留内存几乎是总数的两倍。

任何人都可以解释一下吗?

1 个答案:

答案 0 :(得分:5)

你的质疑最可能的答案是内存碎片化。

分配操作系统内存非常昂贵,因此Erlang会尝试为您管理内存。 当Erlang分配内存时,它会创建一个名为" carrier"的实体,它由许多"块"组成。 Erlang内存(总计)报告所有块大小(实际使用的内存)的总和。 OS报告所有载波大小的总和(使用和预分配的内存总和)。可以从Erlang VM读取块大小和载波大小的总和。如果(块大小)/(载波大小)<< 1,比VM更难以释放运营商。可能有许多大型运营商只使用了几个街区。你可以用:erlang:system_info({allocator,Type})来读它。但有一种更简单的方法。您可以使用Recon库进行检查:

http://ferd.github.io/recon/recon_alloc.html

首先检查:

recon_alloc:fragmentation(current).

和下一个:

recon_alloc:fragmentation(max).

这应该解释Erlang VM和OS报告的总内存之间的差异。如果您通过websockets发送许多小消息,可以通过运行带有2个选项的Erlang来减少碎片:

erl +MBas aobf +MBlmbcs 512

第一个选项会将块分配策略从最佳匹配更改为地址顺序最佳拟合,这可能有助于将更多块压缩到第一个载波中,第二个减少最大多块载波大小,这会使载波更小(这应该可以使它们更容易释放)