免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5602 | 回复: 5
打印 上一主题 下一主题

[Linux] linux内存碎片问题是虚拟地址空间概念还是物理内存概念) [复制链接]

论坛徽章:
1
2015亚冠之浦和红钻
日期:2015-05-26 14:37:09
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-05-25 17:33 |只看该作者 |倒序浏览
大家都知道内存碎片:有内部碎片和外部碎片

网上说  频繁分配内存(malloc或者new)会造成内存碎片:


1、为什么malloc频繁调用和释放,会产生内存碎片?

这里所说的内存碎片是指进程虚拟空间的内存地址不足导致的内存碎片吗?还是由于物理内存不足导致的内存碎片。





2、很多tcmalloc或者ptmalloc这样的库,已经实现了freelist管理内存块的功能,为什么还要使用自己定义的内存池,这不是重复工作嘛??

希望指点一二。很困惑

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
2 [报告]
发表于 2015-05-25 21:39 |只看该作者
内存碎片指的虚拟内存,我的理解是程序员面对的是虚拟内存,而操作系统负责转换虚拟内存和物理内存。
这个不是内存不足导致的碎片,而是大量申请与释放后导致了堆区间存在了大小不同的被占用的内存和被释放的内存,由于这些内存片段是交叉分布的,并不是所有的被占用的内存空间在一起,所有的空闲的内存空间在一起,所以看起来就像存在着碎片。



论坛徽章:
1
2015亚冠之浦和红钻
日期:2015-05-26 14:37:09
3 [报告]
发表于 2015-05-26 11:36 |只看该作者
回复 2# zsszss0000

嗯,我的理解跟你一样。。
再问你一个问题,采用分页机制之后,是不是物理内存层面上的外部内存碎片已经没有意义了,因为我们的分页机制,可以让连续虚拟空间对应的物理内存不连续。

还有一个问题,我们平常采用的ptmalloc函数等,不是已经采用了内存池的技术了嘛。。为什么我们还要自己去设计自己的内存池,这不是已经重复了吗??

论坛徽章:
4
天蝎座
日期:2014-05-20 14:18:39水瓶座
日期:2014-12-19 09:15:322015年迎新春徽章
日期:2015-03-04 10:01:442015年亚洲杯之阿联酋
日期:2015-05-04 10:00:13
4 [报告]
发表于 2015-05-26 11:50 |只看该作者
内存碎片相对于虚拟内存来说的,他与空间是否足够没有关系,产生内存碎片的原因是动态内存的分配机制。内存碎片产生有两种,内部碎片简单说就是分配出去了,但是程序没用到,这部分就浪费了,举个例子,如果内存块分配单位为4K,你申请了10K空间,那你就被分到了3个块,第三块中你只用了1K,另外2K实际是分配给你了,但是你没有用到。外部碎片就是现有的可用内存块不能满足你的申请需求,这部分也不会被分出去。比如一种情况,你连续分配4K大小的小块,然后释放其中的一些(极端情况是隔一个释放一个),后面申请的内存都是大于4K的,那你之前申请的一半的4K内存都是内存碎片无法使用了。  关于内存池,这个我觉得没什么可疑问的吧,如果你有自己特别的内存管理需求,自己定义一个私人定制内存池很正常啊~~以上是我的理解,如果有误欢迎讨论回复 1# kkshaq


   

论坛徽章:
1
2015亚冠之浦和红钻
日期:2015-05-26 14:37:09
5 [报告]
发表于 2015-05-26 14:31 |只看该作者
回复 4# vallrock

内存碎片分为两种:1、是外部碎片   2.是内部碎片,我认为内存碎片的问题最早就是关于物理内存的。因为最开始的操作系统是没有虚拟内存地址的概念的,完全就是直接映射的关系


我认为有两种内存碎片,两种内存碎片从两个角度都可以说的通:
1、从虚拟地址空间角度,就像你之前说的


2、从物理内存角度,此种内存碎片就是关于物理内存的。


对于操作系统的内存管理:一个就是伙伴系统,这是管理以页为单位的物理内存

一个就是slab。这个我还没去了解。

论坛徽章:
0
6 [报告]
发表于 2015-07-18 23:56 |只看该作者
线程虚拟空间的碎片是指空间被划分成了很多不连续的空间导致不能找到一块连续的空间, 因为用户空间的地址范围很大, 所以这种几乎不可能出现.
用户态的malloc/free是基于libc做的, 一般来说libc会批发一块内存当做自己的缓存, 一般不会发生频繁地分配释放导致内存碎片的现象, 除非频繁分配的数据一会儿很大一会儿很小触发到了内核中再分配动作.
不管是用户态要内存要是内核要内存, 归根到底是要调用到kmalloc来分配一块连续的物理页映射给虚拟地址区间, 用户态空间的内存没有物理上连续空间的要求可以调用vmalloc.
物理内存是由伙伴系统管理的, 当你把内存打碎, 某些动作又要分配连续的物理页比如线程的PCB, 这时就会出现分配失败, 但其实是有内存的. 一般是在内存相当紧张的时候又频繁地动态分配时发生, 特别是内核中的某些ko直接调用kmalloc扰乱了内核分配器, 用户态的malloc理论上也会扰动到内核分配器, 但毕竟有个libc的缓冲.

很多tcmalloc或者ptmalloc这样的库,已经实现了freelist管理内存块的功能,为什么还要使用自己定义的内存池,这不是重复工作嘛??
这是重复工作, 但是自己定义内存池仍然有意义, 因为并不是所有人都明白tcmalloc工作原理, 它到底在什么时候会向内核申请或者释放你判断不出来, 你不能预测它对cpu和其他空闲内存会在何时会造成怎样的干扰, 而在某些苛刻的条件下, 自己控制是有益的, 必须要求内存固化线程池化好对资源有个精确的控制, 否则你会发现cpu莫名其妙地冲高, oom不断.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP