【C++】【内存】系列二:堆内存申请与释放

目录

内存申请和释放

内存池 

linux内存申请释放

内存泄漏

内存空洞

内存碎片


内存申请和释放

常见的如:库函数malloc/free、allocate/deallocate, 运算符new和delete,后面两对申请和释放内存实质也是调用了malloc/free,只是做了一些额外的处理。

malloc的分配内存有两个系统调用(不考虑共享内存),一个brk,一个mmap。一般而言,对于内存小于等于128k的调用brk,大于128k的则调用mmap。内存释放的系统调用为sbrkunmmap.。

brk是将数据段(.data)的最高地址指针_edata往高地址推;mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存。这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系。

其他链接:

brk sbrk

深度分析mmap:是什么 为什么 怎么用 性能总结

Linux系统下深究一个malloc/brk/sbrk新内存后的page fault问题

内存的静态分配和动态分配的区别

十问 Linux 虚拟内存管理 (glibc)

内存池 

定义:是一种动态内存分配与管理技术,内存池则是在真正使用内存之前,先申请分配一大块内存(内存池)留作备用。当程序员申请内存时,从池中取出一块动态分配,当程序员释放时,将释放的内存放回到池内,再次申请,就可以从池里取出来使用,并尽量与周边的空闲内存块合并。若内存池不够时,则自动扩大内存池,从操作系统中申请更大的内存池。

作用:当用户向操作系统申请内存次数过多时,容易产生内存碎片(分为外部和内部碎片),为了减少内存碎片的产生,因此提出了内存池技术。

内存池能够减少碎片产生的原理简单如下:假设总内存为4G,如果不设置内存池,是在4G范围的长度内进行内存申请,是按照算法分布在4G内存四处。如果设置内存池(0.5G),那么只会在小范围内进行内存的申请和释放,其他3.5G不受到影响 。 有点类似于把一只拆家狗从卧室关到笼子里面,减少它破坏的范围。

参考链接:

一文看懂内存池原理及创建(C++实现)

linux内存申请释放

Glibc内存管理器首先会向内核申请一大块内存(内存池),用户调用malloc接口时,实际上是从Glibc内存管理器中获取内存,调用free释放内存时,也是将其归还给Glibc内存管理器,Glibc内存管理器充当了二道贩子的角色。

 拓展链接:

深入研究glibc内存管理器原理及优缺点

内存泄漏

在程序运行过程中,用户忘记释放内存或者无法释放内存,导致申请的内存没有归还给操作系统。对于守护(常驻)进程来说,持续的内存泄漏是一场噩梦,最终会导致用户无法申请够用的内存。而对于用完即释放的进程来说,有少量的内存泄漏也不会对整体程序产生影响,因为该进程退出后将其所持有的内存资源归还给操作系统。

检测方法

内存泄漏及其检测方法

解决方法

A,智能指针,采用智能指针自动帮忙销毁内存。

B,采用valgrid等工具扫码代码

B,销毁进程,对于结束任务后的进程及时销毁,避免内存泄漏。

内存空洞

一个内存空洞问题的定位

内存碎片

内存碎片产生原因及终极解决办法

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值