glibc内存泄漏

文章讲述了在glibc库升级到2.29后,由于内存分配策略改变,可能导致应用程序出现内存空洞。主要介绍了问题的原因,涉及brk和mmap的区别,以及M_MMAP_THRESHOLD的动态调整。给出了设置固定阈值和优化内存管理的解决建议。
摘要由CSDN通过智能技术生成

工具链 glibc 库升级到 2.29 版本后,应用程序产生“内存空洞”问题的解决方法

现象描述

某些应用程序频繁调用malloc函数申请内存空间,且申请空间的大小差别比较大,使
用完成后通过free函数释放内存空间,但内存空间依然缓存在glibc中,没有归还操作
系统,导致系统内存不足。

原因分析

Glibc中进程的内存分配由两个系统调用完成: brk和mmap。
● brk是将数据段(.data)的最高地址指针_edata往高地址推; brk分配的内存需要等
到高地址内存释放以后才能释放;
如果先后通过brk申请了A和B两块内存,在B释放之前, A是不可能释放的,仍然
被进程占用,通过TOP查看疑似“内存泄露”。
● mmap是在进程的虚拟地址空间中申请一块空闲的空间。 mmap分配的内存由
munmap释放,内存释放时将立即归还操作系统。
默认情况下,大于等于128KB的内存分配会调用mmap/mummap,小于128KB的内存
请求调用brk,但可以通过修改M_MMAP_THRESHOLD值来调整。
另外, Glibc2.29有一个新特性: M_MMAP_THRESHOLD可以动态调整。
M_MMAP_THRESHOLD的值在128KB到32MB(32位机)或者64MB(64位机)之间动态调
整,如:当申请并释放一个大小为2MB的内存后, M_MMAP_THRESHOLD的值被调
整为2M到2M + 4K之间的一个值。
因此,当应用程序中申请的内存空间数量多,且先后申请的内存空间的大小变化比较
大时,在申请一段大的内存后, M_MMAP_THRESHOLD的值被调大,后续的内存申请
空间大小 < M_MMAP_THRESHOLD时将使用brk申请,而brk需要等到高地址内存释
放以后,低地址内存才能释放。当应用程序没有释放高地址内存时,就导致大量低地
址内存空间不能及时释放,从而产生“内存空洞”,导致系统内存不足。

解决方法

● 在进程启动时,使用int mallopt(int param, int value)函数显式地设置
M_MMAP_THRESHOLD的值为128K,关闭M_MMAP_THRESHOLD动态调整特
性。
● 优化应用程序中内存管理方式,不要频繁申请、释放内存空间,减少内存碎片。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值