一、验证思路和代码

#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <stdlib.h>
#include <sys/mman.h> #define PAGE_SIZE getpagesize()
#define THRESHOLD 32
#define MALLOC_SIZE 20
#define HEAD_SIZE 0x10 int main(int argc, char *argv[])
{
//sbrk(0) 函数用于返回堆顶指针
printf("PAGE_SIZE: %d\n", PAGE_SIZE);
#if 1
int ret = mallopt(M_TRIM_THRESHOLD, THRESHOLD * PAGE_SIZE); //门限设为128K
if( == ret)
{
printf("mallopt err, ret: %d\n", ret);
return -;
}
#endif
/*第一阶段*/
char *temp = (char*)sbrk();
printf("A: heap init addr: %p\n", temp);
sleep();//观察vss, rss, pss, uss 并记录vss1:;rss1, pss1, uss1
char *p1 = (char*)malloc(MALLOC_SIZE * PAGE_SIZE - * HEAD_SIZE);
printf("B: heap init addr: %p, page num: %d\n", sbrk(), ((long)sbrk() - (long)temp) / PAGE_SIZE); //预期:sbrk(0)增大 MALLOC_SIZE*PAGE_SIZE
printf("C: p1 = %p\n", p1);
/*第二阶段*/
sleep();//观察vss, rss, pss, uss 预期vss2=vss1+MALLOC_SIZE*PAGE_SIZE, rss2=rss1, pss2=pss1,uss2=uss1
/*第三阶段*/
for(int i = ; i < MALLOC_SIZE; i++)
{
p1[i * PAGE_SIZE + i] = 'a' + i;
sleep();//观察vss, rss, pss, uss 预期vssi=vss1+MALLOC_SIZE*PAGE_SIZE,
//rssi=rss(i-1) + PAGE_SIZE, pss2i=pss(i-1) + PAGE_SIZE,ussi=uss(i-1) + PAGE_SIZE
} printf("D: heap init addr: %p\n", sbrk());//预期sbrk不变 /*第四阶段*/
//char *p2 = (char*)sbrk(0);
sleep();
char *p3 = (char*)malloc(MALLOC_SIZE * PAGE_SIZE - * HEAD_SIZE);
for(int i = ; i < MALLOC_SIZE; i++)
{
p1[i * PAGE_SIZE + i] = 'a' + i;
sleep();//观察vss, rss, pss, uss 预期vssi=vss2+MALLOC_SIZE*PAGE_SIZE,
//rss3i=rss3(i-1) + PAGE_SIZE, pss3i=pss3(i-1) + PAGE_SIZE,uss3i=uss3(i-1) + PAGE_SIZE
}
printf("E: heap init addr: %p\n", sbrk()); //预期:sbrk(0)增大MALLOC_SIZE * PAGE_SIZE /*第五阶段*/
free(p1);
printf("F: heap init addr: %p\n", sbrk());//预期sbrk(0)不变
/*free释放内存后,因为该内存区域形成空洞,并且空闲内存没有达到内存收缩门限,所以没有还给内核,libc继续做二级管理;
所以还可以访问,不合规范,只做演示*/
printf("\n");
for(int i = ; i < MALLOC_SIZE; i++)
{
if(i % == )
{
printf("\n");
}
printf("p1[i * PAGE_SIZE + i]: %c ", p1[i * PAGE_SIZE + i]);
}
printf("\n"); /*第六阶段*/
free(p3);
printf("G: heap init addr: %p\n", sbrk()); //预期:sbrk(0)减小 THRESHOLD
sleep();//观察vss, rss, pss, uss 预期 减小128K,不会恢复到第一次观察到的值,因为libc没有完全把内存还给系统 return ;
}

二、运行结果

1、在64位机子上跑打印:

 [root@localhost ]# ./malloc_free.o
PAGE_SIZE:
A: heap init addr: 0xf7d000
B: heap init addr: 0xfb2000, page num:
C: p1 = 0xf7d010
D: heap init addr: 0xfb2000
E: heap init addr: 0xfb2000
F: heap init addr: 0xfb2000 p1[i * PAGE_SIZE + i]: ? p1[i * PAGE_SIZE + i]: b p1[i * PAGE_SIZE + i]: c
p1[i * PAGE_SIZE + i]: d p1[i * PAGE_SIZE + i]: e p1[i * PAGE_SIZE + i]: f
p1[i * PAGE_SIZE + i]: g p1[i * PAGE_SIZE + i]: h p1[i * PAGE_SIZE + i]: i
p1[i * PAGE_SIZE + i]: j p1[i * PAGE_SIZE + i]: k p1[i * PAGE_SIZE + i]: l
p1[i * PAGE_SIZE + i]: m p1[i * PAGE_SIZE + i]: n p1[i * PAGE_SIZE + i]: o
p1[i * PAGE_SIZE + i]: p p1[i * PAGE_SIZE + i]: q p1[i * PAGE_SIZE + i]: r
p1[i * PAGE_SIZE + i]: s p1[i * PAGE_SIZE + i]: t
G: heap init addr: 0xf9e000

2、观察:

第一阶段:

三、结论

1、通过观察

malloc内存申请--释放-收缩的更多相关文章

  1. c语言二级指针的使用,malloc内存申请

    #include<stdio.h> #include<stdlib.h> void AllocateMemory(int **pGetMemory, int n) { int ...

  2. C语言学习之我见-malloc和free内存申请及释放函数

    malloc函数负责向计算机申请确定大小的内存空间. free函数负责释放malloc的申请空间. (1)函数原型 void free(void *_Memory); void * malloc(si ...

  3. malloc内存分配与free内存释放的原理

    malloc内存分配与free内存释放的原理 前段时间一直想看malloc的原理,在搜了好几篇malloc源码后遂放弃,晦涩难懂. 后来室友买了本深入理解计算机系统的书,原来上面有讲malloc的原理 ...

  4. [C/C++] malloc内存分配与free内存释放原理

    1.问题的引入: 为什么要使用malloc,主要是因为在代码中,为了节约内存,很多数据都是动态生成的,所以会用malloc,对应于C++中的new,底层还是调用malloc. 2.碎片的问题: 会有内 ...

  5. glibc 内存申请和释放及堆连续检查

    C语言有两种内存申请方式: 1.静态申请:当你声明全局或静态变量的时候,会用到静态申请内存.静态申请的内存有固定的空间大小.空间只在程序开始的时候申请一次,并且不再释放(除非程序结束). 2.自动申请 ...

  6. C++函数中,两个自动释放内存的动态内存申请类

    最近做一个事情,实现一个流程交互,其中主交互流程函数中,涉及较多的内存申请, 而健康的函数,都是在函数退出前将手动申请不再需要的内存释放掉, 使用很多方法,都避免不了较多的出错分支时,一堆的if fr ...

  7. Unity内存申请和释放

    转自:http://www.jianshu.com/p/b37ee8cea04c 1.资源类型 GameObject, Transform, Mesh, Texture, Material, Shad ...

  8. free()后内存不释放问题 - 内存缓冲池技术(转)

    起因 下面这段代码执行后,内存有增无减,增加了200M,iOS平台200M不能接受了 // STL 集合类 void test1() { list<int> mList; for (int ...

  9. php内存申请和销毁

    内存申请 ZendMM使用自身heap层申请内存追踪结果: ZEND_ASSIGN_SPEC_CV_CONST_HANDLER (......) -> ALLOC_ZVAL(......) -& ...

随机推荐

  1. AD9 如何画4层pcb板

    新建的PCB文件默认的是2层板,教你怎么设置4层甚至更多层板. 在工具栏点击Design-->Layer Stack Manager.进入之后显示的是两层板,添加为4层板,一般是先点top la ...

  2. Asp.net Core学习笔记

    之前记在github上的,现在搬运过来 变化还是很大的,感觉和Nodejs有点类似,比如中间件的使用 ,努力学习ing... 优点 不依赖IIS 开源和跨平台 中间件支持 性能优化 无所不在的依赖注入 ...

  3. SVN使用技巧和参考文档总结

    以下文章为网上收集: myEclipse 8.5下SVN环境的搭建(重点推荐) SVN建立版本库,配置用户和权限 Tortoise SVN使用方法,简易图解 版本控制软件SVN使用方法详解 学习笔记 ...

  4. foregroundservice的用处和用法

    由于android的系统资源回收机制,当内存不足的时候,会自动关闭一些后台服务,如果这时候我们的服务正在播放歌曲,由于被关闭,歌曲会被中断,这样会造成很差的用户体验. 这时候我们可以通过在servic ...

  5. Ubuntu Linux 使用桂电校园网 上网

    2016年9月1日 星期四 桂电校园网今天升级新的出校器,旧的出校器已经不能使用,所以本篇博客已经过期,下面的方法已经不能让Ubuntu使用桂电校园网上外网了.详细的原因,请到这个网站查看:校园网计费 ...

  6. 如何使用Hadoop的Partitioner

    如何使用Hadoop的Partitioner 博客分类: Hadoop hadooppartition Hadoop里面的MapReduce编程模型,非常灵活,大部分环节我们都可以重写它的API,来灵 ...

  7. python包管理

    如果是python 项目目录,例如pycharm里新建的python项目,则可以通过from,import导入目录下的文件夹. 如果是普通文件目录,则代码里不能相对方式导入该目录下的文件夹,需要加入要 ...

  8. js 使用中一些需要提醒的点

    1.js 中可以直接使用输出java 变量 <script> var path = '<%=basePath%>'; 2.js重新注册事件后,如何让事件不自动执行? mzTxt ...

  9. Umbraco Examine Search (Lucene.net) french accent

    在项目中使用Umbraco examine search 来search 法语网站时,客户有一个需求,就是 当search  expérience 和 experience 时,需要返回一样的结果. ...

  10. linux下sed批量替换文件内容

    在linux超级终端下编辑文档是件比较麻烦的事情,下面简单介绍一下如何在linux下批量替换文件内容 linuxsed 批量替换多个文件中的字符串 格式: sed -i "s/查找字段/替换 ...