一、验证思路和代码

#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. Poj 1552 Doubles(水题)

    一.Description As part of an arithmetic competency program, your students will be given randomly gene ...

  2. Erlang generic standard behaviours -- gen_server terminate

    gen_server 主体 module 已经分析完了(http://www.cnblogs.com/--00/p/4271982.html),接着,分析下gen_server 中的terminate ...

  3. delphi 线程教学第三节:设计一个有生命力的工作线程

    第三节:设计一个有生命力的工作线程   创建一个线程,用完即扔.相信很多初学者都曾这样使用过. 频繁创建释放线程,会浪费大量资源的,不科学.   1.如何让多线程能多次被复用?   关键是不让代码退出 ...

  4. SpringMvc之参数绑定注解详解之三

    2. @RequestHeader.@CookieValue @RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上. 示例代码: 这是一个Request ...

  5. mongodb循环插入测试数据

    for (var i = 1; i <= 100000; i++) {   db.testdata2.insert( { x : i , name: "MACLEAN" , ...

  6. Android的系统结构简述

    (该图片来自网络) Android系统结构主要分为四层,从上到下依次为,Application层,Application Framework层,lib层,Linux kernel层,下面对这四层进行简 ...

  7. hadoop-2.3.0-cdh5.1.0完全分布式集群配置及HA配置(待)

    一.安装前准备: 操作系统:CentOS 6.5 64位操作系统 环境:jdk1.7.0_45以上,本次采用jdk-7u55-linux-x64.tar.gz master01 10.10.2.57  ...

  8. 19E Fairy

    Once upon a time there lived a good fairy A. One day a fine young man B came to her and asked to pre ...

  9. 使用IDEA编译netty4

    本来计划一天一篇博文的,结果周末加班加的不亦乐乎,对整个项目重构添加国际化的功能,不停的使用native2ascii工具 使用IDEA编译原有的netty4要报错,我修改了下pom.xml,编译成功了 ...

  10. MD5Init-MD5Update-MD5Final

    MD5Init是一个初始化函数,初始化核心变量,装入标准的幻数 MD5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个函数由getMD5ofStr调用,调用之 ...