malloc内存申请--释放-收缩
一、验证思路和代码
#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内存申请--释放-收缩的更多相关文章
- c语言二级指针的使用,malloc内存申请
#include<stdio.h> #include<stdlib.h> void AllocateMemory(int **pGetMemory, int n) { int ...
- C语言学习之我见-malloc和free内存申请及释放函数
malloc函数负责向计算机申请确定大小的内存空间. free函数负责释放malloc的申请空间. (1)函数原型 void free(void *_Memory); void * malloc(si ...
- malloc内存分配与free内存释放的原理
malloc内存分配与free内存释放的原理 前段时间一直想看malloc的原理,在搜了好几篇malloc源码后遂放弃,晦涩难懂. 后来室友买了本深入理解计算机系统的书,原来上面有讲malloc的原理 ...
- [C/C++] malloc内存分配与free内存释放原理
1.问题的引入: 为什么要使用malloc,主要是因为在代码中,为了节约内存,很多数据都是动态生成的,所以会用malloc,对应于C++中的new,底层还是调用malloc. 2.碎片的问题: 会有内 ...
- glibc 内存申请和释放及堆连续检查
C语言有两种内存申请方式: 1.静态申请:当你声明全局或静态变量的时候,会用到静态申请内存.静态申请的内存有固定的空间大小.空间只在程序开始的时候申请一次,并且不再释放(除非程序结束). 2.自动申请 ...
- C++函数中,两个自动释放内存的动态内存申请类
最近做一个事情,实现一个流程交互,其中主交互流程函数中,涉及较多的内存申请, 而健康的函数,都是在函数退出前将手动申请不再需要的内存释放掉, 使用很多方法,都避免不了较多的出错分支时,一堆的if fr ...
- Unity内存申请和释放
转自:http://www.jianshu.com/p/b37ee8cea04c 1.资源类型 GameObject, Transform, Mesh, Texture, Material, Shad ...
- free()后内存不释放问题 - 内存缓冲池技术(转)
起因 下面这段代码执行后,内存有增无减,增加了200M,iOS平台200M不能接受了 // STL 集合类 void test1() { list<int> mList; for (int ...
- php内存申请和销毁
内存申请 ZendMM使用自身heap层申请内存追踪结果: ZEND_ASSIGN_SPEC_CV_CONST_HANDLER (......) -> ALLOC_ZVAL(......) -& ...
随机推荐
- 研华 RISC超低功耗3.5”单板电脑
产品简介: 这是一款搭载TI Sitara AM3358 Cortex-A8 1GHz高性能处理器的RISC 3.5”单板电脑.RSB-4221是一款稳定可靠.性能强大的低功耗平台,专为各种需要丰富I ...
- 接口Comparator和Comparable的区别和联系
1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的. 什么是自定义class: 如 public class Pe ...
- 三 Flask web开发快速入门
1:会话: from flask import Flask, url_for, request, render_template, session from werkzeug.utils import ...
- TS学习之函数
定义函数类型(规定函数参数及函数返回值的类型,若函数没有返回值,则返回类型为null) function add(x: number, y: number): number { return x + ...
- django examples 学习笔记(1)创建一个独立的python环境
pip install virtualenv 创建一个虚拟环境 virtualenv my_env 创建一个独立的环境 source my_env/bin/activate 激活 ...
- [计数问题dp]子数列的个数
http://www.51nod.com/tutorial/course.html#!courseId=15 解题关键:主要是一种思想 $dp[i] = dp[i - 1]*2$ 如果a[i]不在之前 ...
- 8、泛型程序设计与c++标准模板库5.函数对象
1.函数对象 函数对象是STL提供的第四类主要组件,它使得STL的应用更加灵活方便,从而增强了算法的通用性.大多数STL算法可以用一个函数对象作为参数.所谓“函数对象”其实就是一个行为类似函数的对象, ...
- 关于奇异值分解(SVD)的理解
奇异值分解实际上是将一个矩阵,分解成为两个不同维度(行数和列数)上的正交向量集之间的映射变换,奇异值则是变换时的缩放! 例如上面的矩阵M就是一个5维映射到4维的变换矩阵,而SVD分解得到的奇异值和奇异 ...
- Java中编写线程安全代码的原理(Java concurrent in practice的快速要点)
Java concurrent in practice是一本好书,不过太繁冗.本文主要简述第一部分的内容. 多线程 优势 与单线程相比,可以利用多核的能力; 可以方便的建模成一个线程处理一种任务; 与 ...
- 网页编程技术与实例 PDF扫描版
本书主要包括:Web的概念,使用网页编辑工具制作网页,HTML语言的基本结构,JavaScrip和VBScript脚本语言的编程方法,ASP的概念,ASP对象的属性.方法和事件,SQL语言,数据库建议 ...