OTP 15->18升级后,zlib:zip/1引起内存使用升高

文章描述了在从OTP R15B03升级到OTP 18.0后,erlang内存使用显著增加,尤其是binary内存。作者通过排查发现,zlib:zip/1函数会导致每个用户进程额外占用4000 bytes的ref binary。解决方案是使用term_to_binary(Data, [{compressed, 9}])替代zlib:zip/1,以降低内存开销。文章提醒开发者注意zlib:zip/1可能带来的内存问题,并建议避免直接使用或采取手动拷贝返回值的方法。" 78536208,5675373,图形界面IDE Eclipse CDT配置与C/C++项目开发,"['eclipse', 'c语言', 'makefile', '图形界面IDE', 'C++开发']
摘要由CSDN通过智能技术生成

问题

系统原先使用OTP R15B03版本,在升级到OTP 18.0后,CPU下降20%左右(我会告诉你升级就是为了这个么~),但同时发现erlang内存使用比原先高出4倍多。代码、测试环境和用户量均没有变化。通过系统命令发现升级后binary消耗内存显著增加。
升级前,

> erlang:memory(binary).
132252416

升级后,

> erlang:memory(binary).
487293840

排查

参考Erlang-In-Anger使用recon API recon:bin_leak/1和recon:proc_count/2,并没有发现特定进程占用大量binary的现象。系统启动后不接入用户,并没有观察到内存有显著增长。在接入用户并且用户数量稳定一段时间后,binary内存开销逐渐稳定.
升级前后binary内存对比

当清空用户后,binary内存回落。故推测内存开销和用户行为相关。
随机抓取用户pid,通过erlang:process_info(Pid, binary)查看用户binary内存开销。发现OTP升级后,用户进程会多出4000 bytes的ref binary开销。

> process_info(pid(0,4398,0),binary).
{binary,[{
    2017145916624,128,3},
         {
    2017145923600,4000,3},  %% <-升级后出现
         {
    2017144817240,176,2}
         ...]}

系统中每个用户只会处理基本的消息收发,并且消息数据量远远小于4000 bytes,故推测4000 bytes应该是由erlang库函数导致的。搜索erlang源代码,在zlib中有如下

#define DEFAULT_BUFSZ   4000
...
static ErlDrvData zlib_start(ErlDrvPort port, char* buf)
{
    ZLibData* d;

    if ((d = (ZLibData*) driver_alloc(sizeof(ZLibData))) == NULL)
        return ERL_DRV_ERROR_GENERAL;

    memset(&d->s, 0, sizeof(z_stream));

    d->s.zalloc = zlib_alloc;
    d->s.zfree  = zlib_free;
    d->s.opaque = d;
    d->s.data_type = Z_BINARY;

    d->port      = port;
    d->state     = ST_NONE;
    d->bin       = NULL;
    d->binsz     = 0;
    d->binsz_need = DEFAULT_BUFSZ;      /* initial buf size for zlib driver*/
    d->crc       = crc32(0L, Z_NULL, 0);
    d->inflate_eos_seen = 0;
    d->want_crc  = 0;
    return (ErlDrvData)d;
}

在用户执行的代码里,我们使用zlib对用户数据进行压缩并存储

compress(UState) ->
    ...
    zlib:zip(term_to_binary(UData)).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值