linux下的内存管理泄漏

2 篇文章 0 订阅

 

  内存的管理

     在内存管理上份为两层,一个是线性区,类似于 00c73000-00c88000,对应于虚拟内存,它实际上不占用实际物理内存;另外一个是具体的物理页面,它对应我们机器上的物理内存。

         这里要提到一个很重要的概念,内存的延迟分配/按需分配。Linux 内核在用户申请内存的时候,只是给它分配了一个线性区(也就是虚存),并没有分配实际物理内存;只有当用户使用这块内存的时候(比如malloc后,memset一个字节),内核才会分配具体的物理页面给用户,这时候才占用宝贵的物理内存。内核释放物理页面是通过释放线性区,找到其所对应 的物理页面,将其全部释放的过程。

 

1.物理内存:

                   实际内存,常见的有8G  16G  32G  64G等

2.虚拟内存:

                   操作系统(windows或者linux)基于物理内存有限及内存操作效率考虑,设计了虚拟地址访问机制,能够分配比系统现有物理内存更多的内存。虚拟内存使用的是硬盘的空间,硬盘空间动辄几十G上百G,运用了虚拟内存技术,即拿出一部分硬盘空间来充当内存使用,大幅提升了“可用” 内存的大小。(实际上,CPU还是读取物理内存)。

         Linux下两种主要Cache方式:Buffer Cache和Page Cache.前者Buffer Cache针对磁盘块的读写,后者Page Cache针对文件等的读写。这些Cache有效缩短了I/O系统调用(比如 read,write,getdents)的时间
   两个关键概念:
  2.1页面调度
  页面调度是指从磁盘向内存传输数据,以及相反的过程,这个过程之所以被称为页面调度,是因为Linux内存被平均划分成大小相等的页面;通常页面大小为 4KB和8KB(在Solaris中可以用pagesize命令查看)。当可执行程序开始运行时,它的映象会一页一页地从磁盘中读入,与此类似,当某些内存在一段时间内空闲(不被使用),就可以把它们换出到交换空间中,这样就可以把空闲的RAM交给其他需要它的程序使用。
  2.2交换
  交换的概念容易和页面调度通混淆,页面调度是指把一个进程所占内存的空闲部分传输到磁盘上,而交换是指当系统中实际的内存已不够满足新的分配需求时,把整个进程传输到磁盘上,交换活动通常意味着内存不足。其中,交换空间是专门用于临时存储内存的一块磁盘空间,通常在页面调度和交换进程数据时使用。(linux下可配置 /proc/sys/vm/swappiness ,默认为10,也就是达到90,既可以使用swap。看睡眠情况,一般不睡眠情况下,32G物理内存以上,则推荐为8G的交换空间)

  程序操作内存

         系统函数brk mmap等实现的是直接操作内存,brk是通过移动最新的偏移地址得到内存(这个会存在内存空洞),而mmap是找空闲内存,而glic(ptmalloc)等运行库为了内存高效,会进行封装:其多个小128k的内存申请释放后,进行内存合并管理;大于128,用mmap进行直接操作内存,没有合并管理一说。

         因此,可能存在代码free,但是虚拟内存还是占用的。

         对内存空洞要求高的话,建议使用tcmalloc。

  内存查看

1.top命令

        

【大致看下,容易有歧义,建议以free来查看内存情况】

【按(shift+M)会进行内存排序,关注下VIRT和res不要一直涨就可以了】

 

 

2.free

[root@scs-2 tmp]# free

                   total       used       free     shared    buffers     cached
Mem:            128        119           8          0            2               22    从OS的角度来看
-/+ buffers/cache:        95          32                                                             应用程序的内存
swap:          255            0         255

 

第2行-/+ buffers/cache:

-buffers/cache 的内存数: 95 (应用程序的内存,等于第1行的 used - buffers - cached)

+buffers/cache 的内存数:  32 (应用程序的内存,等于第1行的 free + buffers + cached)

可见-buffers/cache反映的是被程序实实在在吃掉的内存,+buffers/cache反映的是可以挪用的内存总数。

第三行数据是交换分区SWAP的,也就是我们通常所说的虚拟内存。 

 (mem)行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用。

used     119 已用内存中包括内核(OS)使用+Application(X, oracle,等)使用的+buffers+cached.

         3.一个进程的内存

      我们通过free命令查看机器空闲内存时,会发现free的值很小。这主要是因为,在Linux系统中有这么一种思想,内存不用白不用,因此它尽可能的cache和buffer一些数据,以方便下次使用。但实际上这些内存也是可以立刻拿来使用的。

  所以 空闲内存=free+buffers+cached=total-used

 

  内存泄漏

         1.依据

         查看一个进程使用的内存,是一个很令人困惑的事情。因为我们写的程序,必然要用到动态链接库,将其加入到自己的地址空间中,但是 / proc/pid/statm 统计出来的数据,会将这些动态链接库所占用的内存也简单的算进来。

这样带来的问题,动态链接库占用的内存有些是其他程序使用时占用的,却算在了你这里。你的程序中包含了子进程,那么有些动态链接库重用的内存会被重复计算。

       

 

         怀疑某处发生了内存泄露,可以查看该进程的maps表,看进程的堆段或者mmap段的虚拟地址空间是否持续增加,如果是,说明很可能发生了内存泄露,如果mmap段虚拟地址空间持续增加,还可以看到各个段的虚拟地址空间的大小,从而可以确定是申请了多大的内存,对调试内存泄露类问题可以起到很好的定位作用。Rss-Resident Set Size 实际使用物理内存(包含共享库占用的内存) 

 

 

学习链接

https://www.jianshu.com/p/38a4bcf564d5  内存机制,包括示例内存释放

https://www.cnblogs.com/yangykaifa/p/7397497.html   mtrace 定位泄漏

https://testerhome.com/articles/20547    gdb定位泄漏

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值