一、验证思路和代码
#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 ", PAGE_SIZE); #if 1 int ret = mallopt(M_TRIM_THRESHOLD, THRESHOLD * PAGE_SIZE); //门限设为128K if(0 == ret) { printf("mallopt err, ret: %d ", ret); return -1; } #endif /*第一阶段*/ char *temp = (char*)sbrk(0); printf("A: heap init addr: %p ", temp); sleep(20);//观察vss, rss, pss, uss 并记录vss1:;rss1, pss1, uss1 char *p1 = (char*)malloc(MALLOC_SIZE * PAGE_SIZE - 2 * HEAD_SIZE); printf("B: heap init addr: %p, page num: %d ", sbrk(0), ((long)sbrk(0) - (long)temp) / PAGE_SIZE); //预期:sbrk(0)增大 MALLOC_SIZE*PAGE_SIZE printf("C: p1 = %p ", p1); /*第二阶段*/ sleep(20);//观察vss, rss, pss, uss 预期vss2=vss1+MALLOC_SIZE*PAGE_SIZE, rss2=rss1, pss2=pss1,uss2=uss1 /*第三阶段*/ for(int i = 0; i < MALLOC_SIZE; i++) { p1[i * PAGE_SIZE + i] = 'a' + i; sleep(1);//观察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 ", sbrk(0));//预期sbrk不变 /*第四阶段*/ //char *p2 = (char*)sbrk(0); sleep(2); char *p3 = (char*)malloc(MALLOC_SIZE * PAGE_SIZE - 2 * HEAD_SIZE); for(int i = 0; i < MALLOC_SIZE; i++) { p1[i * PAGE_SIZE + i] = 'a' + i; sleep(1);//观察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 ", sbrk(0)); //预期:sbrk(0)增大MALLOC_SIZE * PAGE_SIZE /*第五阶段*/ free(p1); printf("F: heap init addr: %p ", sbrk(0));//预期sbrk(0)不变 /*free释放内存后,因为该内存区域形成空洞,并且空闲内存没有达到内存收缩门限,所以没有还给内核,libc继续做二级管理; 所以还可以访问,不合规范,只做演示*/ printf(" "); for(int i = 0; i < MALLOC_SIZE; i++) { if(i % 3 == 0) { printf(" "); } printf("p1[i * PAGE_SIZE + i]: %c ", p1[i * PAGE_SIZE + i]); } printf(" "); /*第六阶段*/ free(p3); printf("G: heap init addr: %p ", sbrk(0)); //预期:sbrk(0)减小 THRESHOLD sleep(20);//观察vss, rss, pss, uss 预期 减小128K,不会恢复到第一次观察到的值,因为libc没有完全把内存还给系统 return 0; }
二、运行结果
1、在64位机子上跑打印:
1 [root@localhost ]# ./malloc_free.o 2 PAGE_SIZE: 4096 3 A: heap init addr: 0xf7d000 4 B: heap init addr: 0xfb2000, page num: 53 5 C: p1 = 0xf7d010 6 D: heap init addr: 0xfb2000 7 E: heap init addr: 0xfb2000 8 F: heap init addr: 0xfb2000 9 10 11 p1[i * PAGE_SIZE + i]: ? p1[i * PAGE_SIZE + i]: b p1[i * PAGE_SIZE + i]: c 12 p1[i * PAGE_SIZE + i]: d p1[i * PAGE_SIZE + i]: e p1[i * PAGE_SIZE + i]: f 13 p1[i * PAGE_SIZE + i]: g p1[i * PAGE_SIZE + i]: h p1[i * PAGE_SIZE + i]: i 14 p1[i * PAGE_SIZE + i]: j p1[i * PAGE_SIZE + i]: k p1[i * PAGE_SIZE + i]: l 15 p1[i * PAGE_SIZE + i]: m p1[i * PAGE_SIZE + i]: n p1[i * PAGE_SIZE + i]: o 16 p1[i * PAGE_SIZE + i]: p p1[i * PAGE_SIZE + i]: q p1[i * PAGE_SIZE + i]: r 17 p1[i * PAGE_SIZE + i]: s p1[i * PAGE_SIZE + i]: t 18 G: heap init addr: 0xf9e000
2、观察:
第一阶段:
三、结论
1、通过观察