Mmap和Valgrind,Mmap不会增加堆大小。

3

我正在参加大学的操作系统课程,其中我们被要求使用mmap实现简单的malloc。现在我已经让它正常工作了,我尝试使用valgrind检测是否还有任何错误。无论是否释放内存,valgrind都看不到任何内存泄漏。以下是一个C代码示例:

int main()
{
    int psize = getpagesize(),i;
    int *ptr = mmap(NULL, psize, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    for(i = 0; i < psize/4; i++) ptr[i] = i;
    for(i = 0; i < psize/4; i++) printf("%d\n", ptr[i]);
    return 0;
}

我们可以使用gcc编译它,并使用valgrind进行检测。以下是valgrind的返回结果:

==17841== Memcheck, a memory error detector
==17841== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==17841== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==17841== Command: ./test
==17841== 
------------ printing numbers from 0 to 1023
==17841== 
==17841== HEAP SUMMARY:
==17841==     in use at exit: 0 bytes in 0 blocks
==17841==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==17841== 
==17841== All heap blocks were freed -- no leaks are possible
==17841== 
==17841== For counts of detected and suppressed errors, rerun with: -v
==17841== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

这是一些意外情况,通常我们希望在退出程序之前将页面取消映射以查看此类消息。

起初我认为页面可能会被惰性映射,这就是为什么我强制执行了对该页面上某些内容进行更改和打印的操作,但正如我们所看到的,这不是问题所在。

这可能是valgrind或我对mmap和valgrind工作方式的理解有误。


valgrind 与系统的 malloc 相关(或提供自己的 malloc)。我不确定它能否使用你自己的 malloc,除非你在你的 malloc 实现中提供了特定的钩子! - Basile Starynkevitch
1个回答

10

堆(heap)与通过mmap获得的内存是分开的。Unix进程获取内存的基本方式有两种:

  • 通过brk(2)/sbrk(2)增加 "break" 来增加堆 - 这是堆(heap)
  • 通过使用mmap映射内存 - 这些独立于堆

程序内存结构有一张好图片:

Anatomy of a Program in Memory

这可能是valgrind或我的对mmap和valgrind工作方式的理解出了问题。阅读 memcheck手册可能会有所帮助,特别是关于自定义分配器的部分。要点是为了进行泄漏检查,由mmap分配的块对于valgrind是不可见的。它只拦截malloccallocfreenew等操作。
一些使用mmap分配的内存区域被valgrind跟踪。例如,当malloc选择在堆外使用mmap内存时会发生这种情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接