内存碎片

来源:互联网 发布:修改手机型号软件 编辑:程序博客网 时间:2024/04/27 16:09

一程序, 使用stl容器保存大量数据

 

top/pmap看, 进程的writtable/private空间很大, 明显不合理;

 

使用malloc_stats 看, in use的内存正常。

 

那么唯一合理的解释是:

1 内存碎片

2 进程调用了free时, 并没有向OS归还内存; free内部有缓存机制以便下次malloc

3 和stl容器无关

 

 

通常所谓的stl的allocator分配器, 其内部缓存, 通常是应用层的缓存: clear掉容器内所有对象时, 只是把内存还给了allocator; allocator的生命周期结束时, 肯定会调用free之类的操作向OS归还内存。

 

至于最终是否归还, 就是malloc/free自己的事情了。 目前来看malloc/free肯定有缓存机制

 

 

 

 

 

 

 

 

推荐一个tcallocator, 可以不用修改代码, 只连接一个库就能使用。 见code.google

 

 

 

 

=========

记一下解决这个问题时的思路过程。。

1 怀疑stl容器本身没释放

2 怀疑stl的allocator没释放

3 怀疑其他地方漏掉free之类的

4 内存碎片

==其中第2个是不用考虑的, 特别是在使用默认的allocator时

 

 

 

 

 

 

 

==========

从一篇帖子上看到, 从效率角度上说, 自实现的多线程情况下使用mutex的allocator, 还不如直接new/delete。

大概时间: malloc 花掉500 nanosecond, 而一次加锁过程需要2000 nano

 

此次没实际验证; 但是从我个人之前的一次项目过程中得到佐证。 2年前自己写过一个多线程+mutex的allocator, 启动加载大量数据时, 确实比直接new慢许多

 

 

 

 

 

 

 

==========

一种避免内存碎片的小技巧

typedef struct _NODE

{

    char *pData;

    int nLength;

} Node;

使用的时候:

Node *pNode = (Node*)malloc(sizeof(Node));

pNode->Data = (char*)malloc(pNode->nLength);

这样是没有任何问题的,但是却有内存碎片的产生;

 

解决办法:

typedef struct _Node

{

   int nLength;

    char pData[1];

} Node;

具体的使用方法:

int nDataLength = (nLenght == 0 ? 1 : nLength) - 1;

Node *pNode = (Node*)malloc(sizeof(Node) + nDataLength);

这样就避免了内存碎片的问题。

 

另外上面又有一个小技巧就是对齐问题:

由于C语言中编译器是四字节对齐的,所以上面需要加上nPedding[3]来占位。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 喂了宝宝熊胆粉怎么办 不小心擦伤了皮怎么办 吃了减肥药拉肚子怎么办 遇到他心通的人怎么办 被茅山术害了怎么办 鱼缸鱼身上烂了怎么办 鳄鱼龟皮肤烂了怎么办 墨水渗透进皮肤里了怎么办 中药渗透到皮肤里怎么办 甘露醇渗透到皮肤下怎么办 水银弄到眼睛里怎么办 水银粘到皮肤上怎么办 榴莲和虾同吃了怎么办 吃榴莲和虾中毒怎么办 榴莲和虾一起吃怎么办 狗被别人下毒了怎么办 大掌门2没存元宝怎么办 大掌门2转换阵容怎么办 率土之滨s2绝版怎么办 异界气息的装备怎么办 vivo电板没电了怎么办 门套拼接有缝隙怎么办 公司如果一直没有上税收入怎么办 赛车输了俩百万怎么办 交pk金员工不交怎么办 员工不想交pk金怎么办 心悦光环领错角色怎么办 心悦光环领错了怎么办 扑克牌1到13洗后怎么办 南通长牌没钱了怎么办 镇魔曲手游阵营人数已满怎么办 镇魔曲忘记在哪个区怎么办 登录镇魔曲卡在实名验证怎么办 电脑玩联盟花屏怎么办 优盘文件或目录损坏怎么办 苹果下吃鸡设备不兼容怎么办 龙之谷账号忘了怎么办 不花钱的排风除湿怎么办 苹果平板id密码忘了怎么办 苹果平板忘记id及密码怎么办 饥荒抓到的兔子怎么办