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(......) -& ...
随机推荐
- git常见使用情境整理
一.版本回退 回退到某个commit版本的方法如下: 1. 查看commit历史 git log 找到想要回退的版本的号码,eg:f765889 2. 回退到该版本 git reset f765889 ...
- C#如何对DataTable中的数据进行条件搜索
经常遇到将数据库中的数据读取到DataTable中的时候再次对DataTable进行条件筛选,下面的筛选的一个例子: DataRow[] dr = dt.Select("token = '& ...
- zabbix 系列 (1)安装
安装server http://blog.csdn.net/xiegh2014/article/details/54988548 安装 agent http://m.blog.csdn.net/wu2 ...
- 关于javaScript事件委托的那些事
今天是第一次写稿,还是有那么一丢丢小鸡冻...回归正题啦... 关于javaScript事件委托不得不说的那些事,为什么要使用事件委托? 我们可以这么说,假设老板要分配一项任务,首先要秘书叫A君来到办 ...
- 菜鸟攻城狮3(Holle World)
1.创建一个HolleWorld.java文本文件 2.代码:public class HolleWorld { public static void main(String[] args) { Sy ...
- Codeforces 1107G Vasya and Maximum Profit 线段树最大子段和 + 单调栈
Codeforces 1107G 线段树最大子段和 + 单调栈 G. Vasya and Maximum Profit Description: Vasya got really tired of t ...
- 为组件设定UI
-----------------siwuxie095 工程名:CustomizeSwing 包名:com.siwuxie095.swing 类 ...
- Shrio00 Shiro认证登录、权限管理环境搭建
基础环境准备: JDK -> java version "1.8.0_101" MAVEN -> Apache Maven 3.5.0 1 导入依赖 mysql驱动 m ...
- sell02 展现层编写
# API ###商品列表 ``` GET /sell/buyer/product/list ``` 参数 ``` 无 ``` 返回 ``` { "code": 0, " ...
- 怎么触发gridview 的SelectedIndexChanged事件?
<asp:GridView onclick="javascript:SelectedIndexChanged()" ID="GridView1" runa ...