》小伙2000元1500给MM买了个手机,留500元吃饭开房,坐电瓶车找MM。MM说:你是个好人,但我们真的不合适。上面这段是段子,如果我们优化一下:一个小伙子700块钱租了一辆BMW5,然后去批发市场300块钱买了99朵玫瑰,跟MM说他喜欢结伴而行那些浪漫小吃店最多能花100块,MM说,你好帅!看,这就是优化的力量!昨天在本叔的VIP群里,小伙伴们兴高采烈地讨论了一个问题,他们讨论的程序是这样的:这个程序挺有意思的,在一个while循环中,一直使用malloc()分配内存,直到世界末日,这个例子里面其实涉及到很多内存管理的知识点,malloc函数返回的内存是不是虚拟内存还是物理内存?什么时候分配物理内存?什么时候malloc函数会导致分配不成功?malloc分配的page是什么?上面的程序是在哪里吃内存的?-----?----初看:第一个问题,malloc分配的内存是虚拟内存还是物理内存。这是研究这个问题的初步认识,也是最基本的认识。如果这种理解是错误的,关于这个问题的讨论就会误入歧途。其实如果你理解了操作系统为什么要区分虚拟内存和物理内存,你就会明白为什么malloc返回的内存是虚拟的。【malloc是如何分配的,见《奔跑吧Linux内核》的2.8章。本章开头的问题也很经典】既然是虚拟的,那么什么时候需要物理内存呢?没有物理内存不能天天谈虚拟化,那太虚幻了,物理内存只是让你安心而已。【第三个问题:关于malloc之后如何分配物理页,什么类型的物理内存,建议大家阅读《奔跑吧Linux内核》第165~168页】第二个问题,什么会导致malloc函数分配错误?成功。这个问题有点难。想明白就先发个图吧。这张图是32位处理器的堆空间示意图。它是从数据段末尾到1GB。这么大的空间用于堆空间,也就是malloc。但是glibc会使用上面的mmap空间,所以如果上面的程序运行在32位的系统上,那么本次测试3GB的虚拟空间可能已经满了。那么对于64位程序,最大可以分配多少虚拟空间呢?在x86中,这个宏定义defineTASK_SIZE_MAX((1UL<<47)-PAGE_SIZE),那么它有多大呢?你可以算一下,大约是128TB。问题四:分配失败有两种可能。一是虚拟空间没了,也就是128TB的空间被吃光了。另外一个是物理内存不够用,也是malloc机制本身的管理系统。它还需要维护成本。如果你继续毫无节制地使用malloc,它本身就会耗尽内存。这是管理的两个方面。在许多情况下,管理成本也是一个考虑因素。对比上面两个图,再看Active(anon),后图已经吃掉4GB多了,所以dryrunningmalloc也是有管理成本的。有兴趣的可以在上面的程序中修改MEM_SIZE的大小,观察它们的变化:比如在最后加一个sleep函数,让程序呆在那里,后面我们会剖析。如果大家观察到什么好的现象,可以在评论区留言。
