mordorwww 发表于 2014-05-05 21:43

是否malloc每次调用都会进入内核?

本帖最后由 mordorwww 于 2014-05-05 21:44 编辑

malloc在glibc中,后者现在 都是共享库了吧

那么进入mallic后, malloc要为每个进程管理内存, 必须访问每个进程的内存管理状态数据, malloc如何知道是哪个进程在调用它呢?是不是要进内核获取当前进程 pid?

l4rmbr 发表于 2014-05-06 00:39

本帖最后由 l4rmbr 于 2014-05-06 00:45 编辑

回复 1# mordorwww


不会。malloc是属于C库层次的函数,是对系统调用的封装。它是实现在glibc中的一个库函数。

Glibc有自己的堆管理算法。它会一次性向OS"批发"比较大量的内存,然后以自己的堆管理算法来维护这部分内存,
以响应用户通过malloc等接口进行分配,但库存不足时,会再向OS“补仓”。
感兴趣者可以自行搜索相关信息。

Glibc的“批发”和”补仓“其实就是通过mmap, brk等系统调用, 在进程地址空间生成一个anonymous private映射,
在必要时通过brk调用进行扩容或减容。

Glibc是共享库没错。但“共享”的意思是只有一份拷贝在内存中,但每个使用它的进程都会把其映射到自己的进程空间。
因此对于malloc的使用其实是per-process的。

openspace 发表于 2014-05-06 08:00

记得当前实习面试的时候被问到这个问题,当时想应该是用户态自己做了内存管理算法

楼上讲的很清楚

学习

humjb_1983 发表于 2014-05-06 12:50

完全同意2楼

mordorwww 发表于 2014-05-06 18:56

举例,每个进程的堆的边界在哪里,malloc如何知道

Tinnal 发表于 2014-05-06 21:01

回复 5# mordorwww

通过sbrk(0)可以得到当前的堆顶。
整个程序刚才始运行时sbrk(0)得到的就是堆底。
运行过程中当可以通过sbrk(相对增加值)或brk(绝对地址)去扩展堆。
参见:http://linux.die.net/man/2/brk

堆由glibc的malloc方案去管理。
malloc的原理可以到百度文库搜索,有很多现成的分析。下面就是其中一编:
http://wenku.baidu.com/view/c7aebc05bed5b9f3f90f1cbc.html


   

mordorwww 发表于 2014-05-06 21:45

本帖最后由 mordorwww 于 2014-05-06 21:50 编辑

所以我问你malloc查询进程堆边界调用sbrk要不要进内核

Tinnal 发表于 2014-05-07 08:38

回复 7# mordorwww

这个分析很简单:
1. 实践派:写个程序,strace一下就行。调了什么系统调用,返回值得是多少,一清二楚。
2. 理论分析派:man 一下sbrk手册,写得很清楚,在Linux下,brk和sbrk库调用,都是使用brk系统调用的。


在linux系统调用中。如果传0,就代表返回当前堆顶(第一次调用时和堆底同值,可以由strace结果进行验证)。

以下的代码摘自2.6.34.10内核mm/mmap.c文件。
SYSCALL_DEFINE1(brk, unsigned long, brk)
{
        //<...>
        unsigned long min_brk;
        //<...>
#ifdef CONFIG_COMPAT_BRK
        min_brk = mm->end_code;
#else
        min_brk = mm->start_brk;
#endif
        if (brk < min_brk)
                goto out;

        //<...>
out:
        retval = mm->brk;//<--- 这就是内核管理的进程的栈顶!
        //<...>
        return retval;
}

daniel_11 发表于 2014-05-07 10:17

貌似楼主的问题是会不会每次产生系统调用?

Tinnal 发表于 2014-05-08 08:57

不会,glibc 查询后,会存到进程空间的管理变量中。以后除非堆不够用,不然不会再次调用brk去扩堆。


malloc如何知道是哪个进程在调用它呢?是不是要进内核获取当前进程 pid?

malloc不需要知道他的PID是多少,是那个进程序调用它的?因为so的数据段是不同享的,每一个用到这个so的程序,都会在自身的程序空间存在一份独立的拷贝(虚拟进址和物理地址都不一样)。malloc只需要访问他的变量好的。
进程1放访问到的是进程1的变量2, 进程2放问到的是进程2的变量1, 不需要malloc去区分他是谁。
页: [1]
查看完整版本: 是否malloc每次调用都会进入内核?