TLPI 第7章 练习:Memory Allocation
笔记和练习博客总目录见开始读TLPI。练习 7-1修改清单 7-1free_and_sbrk.c中的程序在每次执行 malloc() 后打印出当前程序断点的值。运行程序时指定一个较小的分配块大小。这将演示 malloc() 并不是每次调用都使用 sbrk() 来调整程序断点而是周期性地分配较大的内存块然后将其中的小块返回给调用者。此程序在memalloc目录下。其用法$ ./free_and_sbrk -h Usage: ./free_and_sbrk num-allocs block-size [step [min [max]]]前面2个参数控制内存分配后面三个控制内存释放。只有1处使用了malloc:$ grep malloc free_and_sbrk.c ptr[j]malloc(blockSize);errExit(malloc);然后在brk(2)中Calling sbrk() with an increment of 0 can be used to find the current location of the program break.要理解这个练习还需参考图Figure 6-1: Typical memory layout of a process on Linux/x86-32。首先观察到一个奇怪的现象$ ./free_and_sbrk110240000Initial program break: 0x25755000 Allocating1*10240000 bytes Programbreakis now: 0x25755000 Freeing blocks from1to1insteps of1After free(), programbreakis: 0x25755000 $ ./free_and_sbrk100010240Initial program break: 0x16302000 Allocating1000*10240 bytes Programbreakis now: 0x16cca000 Freeing blocks from1to1000insteps of1After free(), programbreakis: 0x16302000分配同样的内存总量但是一个program break没变而另一个变了。在malloc(3)中找到了答案Normally, malloc() allocates memory from the heap, and adjusts the size of the heap as required, us‐ing sbrk(2). When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc()implementation allocates the memory as a private anonymous mapping using mmap(2). MMAP_THRESHOLD is128 kB by default也就是说第一个一次性分配10M内存使用了mmap根本就没从堆中分配。mmap使用的是堆和栈之间的未分配内存。至于MMAP_THRESHOLD的大小可以这么看gdb-pPID(gdb)p mp_.mmap_threshold例如$ gdb-p$$...(gdb)p mp_.mmap_threshold$1131072运行$ ./ex7-110010240Initial program break: 0x29e13000 Allocating100*10240 bytes13:Programbreakchanged from 0x29e13000 to 0x29e3600026:Programbreakchanged from 0x29e36000 to 0x29e5700040:Programbreakchanged from 0x29e57000 to 0x29e7a00054:Programbreakchanged from 0x29e7a000 to 0x29e9d00068:Programbreakchanged from 0x29e9d000 to 0x29ec000082:Programbreakchanged from 0x29ec0000 to 0x29ee300096:Programbreakchanged from 0x29ee3000 to 0x29f06000 Programbreakis now: 0x29f06000 Freeing blocks from1to100insteps of1After free(), programbreakis: 0x29e13000大概每隔13次分配就会调整一次program break很怀疑就是128K$bc-lbc1.07.1 Copyright1991-1994,1997,1998,2000,2004,2006,2008,2012-2017 Free Software Foundation, Inc. This isfreesoftware with ABSOLUTELY NO WARRANTY. For detailstypewarranty.14*10240/1024140.0000000000000000000013*10240/1024130.00000000000000000000quit代码改动如下// ex7-1.cvoid*prevBrk,*curBrk;...prevBrkcurBrksbrk(0);printf(Initial program break: %p\n,prevBrk);printf(Allocating %d*%d bytes\n,numAllocs,blockSize);for(j0;jnumAllocs;j){ptr[j]malloc(blockSize);curBrksbrk(0);if(curBrk!prevBrk){printf(%d:Program break changed from %p to %p\n,j,prevBrk,curBrk);prevBrkcurBrk;}if(ptr[j]NULL)errExit(malloc);}练习 7-2.高级实现 malloc() 和 free()。 参考C编程语言第二版中的实现。