内容:Memory
1. 几个基本概念,page、frame、paging、segment。
进程分配内存的两种模式,一个使用 exec 系列函数,一个使用 programmatically(malloc 等函数)。
重要的 segment 有 text segment(存放代码等等,一般在进程的生命周期中不变)、data segment
(存放数据,可以用一些函数来调整大小,但是低位端位置不变)、stack segment(随着使用的堆栈
变大而变大,但不变小...)
2. 内存的静态分配和自动分配。前者是对于 static 变量或者全局变量,一旦开始就分配,即一直存在到最后。
后者是临时变量,如调用函数。值得注意的是:
In GNU C, the size of the automatic storage can be an expression that
varies. In other C implementations, it must be a constant.
3. 内存的动态分配不为 C 语言本身支持,不像 C++。基本方法是
void * malloc (size_t size)分配到的内存没有初始化(calloc 会做清零,clear allocate),因此可以用 memset 来
进行初始化。分配后应检测返回指针是否为 NULL。malloc 返回的一个块多数情况下对齐
(这样可以存储任意类型的数据)过了,地址为 8 的倍数(64 位系统里面是 16 的倍数),
在一些特殊情况下(page 的边界)可以利用 memalign、posix_memalign、vlign 来返回
对齐(2 的幂次)的内存块。free 的内存很少被返还给操作系统,多数情况被留作后面
malloc 使用。如果需要调整已经 malloc 的块的大小,使用 realloc。glibc 不会将分配的块
对 2 的幂次进行向上取整。
4. 一次性分配很大的内存(大于一个 page)会使用向 2 的幂次取整的策略,使用 mmap
相关的函数 mallopt,这种分配得到的内存在 free 时会返回给操作系统。
5. 如何调整 malloc 的行为?使用 mallopt 调整一些参数的值(malloc.h),如
M_TRIM_THRESHOLD(返回给 OS 的内存的一个阈值)、M_MMAP_THRESHOLD
(大于此值的内存分配请求使用 mmap 系统调用)等等。
6. 分配的内存来自堆(heap),可以用
int mcheck (void (*abortfn) (enum mcheck_status status))来检查分配内存的一致性,调用在 malloc 之前。
enum mcheck_status mprobe (void *pointer)为特定的一块内存做检查。这都是 GNU extension。(mcheck.h)
7. 为了方便调试,glibc 为用户提供了 malloc 等等函数的钩子(hook),如 __malloc_hook
对应的是一个函数指针,
void *function (size_t size, const void *caller)其中 caller 是调用 malloc 返回值的接受者(一个指针的地址)。另外有 __malloc_initialize_hook
函数指针,仅仅会调用一次(第一次分配动态内存时)。(malloc.h)
8. 一些使用 malloc 的统计量(SVID 扩展)可以用 struct mallinfo 储存,
可调用
struct mallinfo mallinfo (void)获得。
9. 如何检测 memory leakage?glibc 提供了一个函数
void mtrace (void)及其反作用
void muntrace (void)这时会依赖于一个环境变量 MALLOC_TRACE 所指的文件,把一些信息记录在该文件中
| 论坛热门帖子: | [lch203] 写得蛮好的linux学习笔记(10-21) [黑马制造] 学习java的30个目标(10-19) [笑傲股林] 做测试半年了,有点迷茫,应该再学些什么提高自己的测试水平和测试能力呢?(10-19) [udp8589] 大家用google的来吱一声? 用百度的~~也来报道下?(10-18) [沂偌掳兆] 本人总结的一些认为C++比较经典的书籍,希望对大家有用(10-18) |
| TAG标签: | 笔记 void obstack int 分配 struct 使用 可以 内存 一个 |
注册
个人空间
