一、验证思路和代码

#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. 研华 RISC超低功耗3.5”单板电脑

    产品简介: 这是一款搭载TI Sitara AM3358 Cortex-A8 1GHz高性能处理器的RISC 3.5”单板电脑.RSB-4221是一款稳定可靠.性能强大的低功耗平台,专为各种需要丰富I ...

  2. 接口Comparator和Comparable的区别和联系

    1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的. 什么是自定义class: 如 public class Pe ...

  3. 三 Flask web开发快速入门

    1:会话: from flask import Flask, url_for, request, render_template, session from werkzeug.utils import ...

  4. TS学习之函数

    定义函数类型(规定函数参数及函数返回值的类型,若函数没有返回值,则返回类型为null) function add(x: number, y: number): number { return x + ...

  5. django examples 学习笔记(1)创建一个独立的python环境

    pip install virtualenv   创建一个虚拟环境 virtualenv   my_env      创建一个独立的环境 source my_env/bin/activate   激活 ...

  6. [计数问题dp]子数列的个数

    http://www.51nod.com/tutorial/course.html#!courseId=15 解题关键:主要是一种思想 $dp[i] = dp[i - 1]*2$ 如果a[i]不在之前 ...

  7. 8、泛型程序设计与c++标准模板库5.函数对象

    1.函数对象 函数对象是STL提供的第四类主要组件,它使得STL的应用更加灵活方便,从而增强了算法的通用性.大多数STL算法可以用一个函数对象作为参数.所谓“函数对象”其实就是一个行为类似函数的对象, ...

  8. 关于奇异值分解(SVD)的理解

    奇异值分解实际上是将一个矩阵,分解成为两个不同维度(行数和列数)上的正交向量集之间的映射变换,奇异值则是变换时的缩放! 例如上面的矩阵M就是一个5维映射到4维的变换矩阵,而SVD分解得到的奇异值和奇异 ...

  9. Java中编写线程安全代码的原理(Java concurrent in practice的快速要点)

    Java concurrent in practice是一本好书,不过太繁冗.本文主要简述第一部分的内容. 多线程 优势 与单线程相比,可以利用多核的能力; 可以方便的建模成一个线程处理一种任务; 与 ...

  10. 网页编程技术与实例 PDF扫描版

    本书主要包括:Web的概念,使用网页编辑工具制作网页,HTML语言的基本结构,JavaScrip和VBScript脚本语言的编程方法,ASP的概念,ASP对象的属性.方法和事件,SQL语言,数据库建议 ...