09 | 深入理解堆:malloc和内存池是怎么回事?
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了堆内存管理的重要性以及相关的性能优化和常见问题排查方法。从malloc函数的基本功能和实现原理到内存的精细化管理,包括空闲链表的概念和使用链表进行分配和回收的算法,文章详细介绍了堆内存管理的常用方法。其中,分桶式内存管理和伙伴系统被重点讨论。分桶式内存管理采用多个链表,将相同大小的内存区域挂载到同一个链表上,以提高分配内存的效率和碎片控制。而伙伴系统则动态地根据分配请求将大的内存分割成小的内存,并在释放内存时合并相邻的空闲内存,从而提高内存管理的弹性。此外,文章还介绍了malloc的实现策略的灵活性,以及Tcmalloc库在多线程情况下性能提升的改进。最后,文章提到了自己动手实现内存管理库的意义,以及如何更好地解决内存问题并深入理解内存管理的技术细节。通过本文的学习,读者可以快速了解堆内存管理的重要性、常见方法和技术细节,提高自己分析和解决内存问题的能力。
《编程高手必学的内存知识》,新⼈⾸单¥59
全部留言(13)
- 最新
- 精选
- 大豆老师,我有个疑问,通过mmap分配的内存是在进程的映射区还是堆中,还是都有?
作者回复: 在进程的映射区中。不用太在意这个概念的区分,你要在意的是,mmap出来的内存区域被拿去做什么了。它可以用于malloc分配堆内存,也可以用于协程的栈内存。所以一块内存区域到底是什么,取决于你怎么用他,而不是它自己的地址在哪里。换句话说,根据地址划分的区域不是绝对的,根据它的作用,内存区域的性质也是可以发生变化的。
2021-11-1213 - qinsi看完感觉自己可以实现个valgrind了,不过又觉得少了亿点点细节。于是查了下valgrind的实现,发现只有用到了preload这点是一样的。剩下的部分valgrind相当于实现了一个虚拟机,将机器指令转成虚拟机IR,插桩,再通过JIT生成机器指令执行。这样看来Java字节码增强就是个弟弟阿… 另外llvm因为本身就有IR,所以就可以直接在IR上做,据说asan就是这么实现的。
作者回复: 厉害,你调查得很深入了。
2021-11-127 - LDxy老师,为什么很多用C语言做开发的人都说glibc里面的内存分配malloc的性能不行,所以要自己实现一个动态内存管理机制。可我也没看出glibc里面的malloc有啥大问题,自己去重新实现一套内存管理,真的能比标准库的性能提升吗?而且究竟该怎么测试动态内存管理机制的性能,似乎也无从下手。而且,好像就只有C程序员在意动态内存分配的性能问题,其他语言比如C++,Java的程序员就不怎么关心动态内存分配的性能问题。
作者回复: tcmalloc和jemalloc都比malloc的性能好。c++也很在意这一点的。java是内存全部自己托管了。不存在这个问题。
2021-11-2322 - 慢动作error里也有地址,这额外日志没有给出额外的信息?
作者回复: 嗯。这里主要演示了一下如何做函数替换,其他的信息,比如当时的调用栈什么的,需要更多调试器的实现原理,所以我们就没再讲了。如果有兴趣可以参考一下gdb如何打印调用栈,valgrind如何追踪泄漏内存。
2021-11-122 - 郑童文请问老师malloc函数用mmap向系统申请一大块内存的时候,这一大块内存就已经映射到物理内存了吗? 还是在malloc从这一大块内存中分配一小块内存给进程时,才会把这一小块内存映射到物理内存?
作者回复: 不会mmap,malloc都不会使虚拟内存映射到物理内存。只有你在访问他的时候才会触发缺页中断。
2021-12-071 - 🐮老师,你好,请教个问题,之前函数重载这块使用比较多的是通过编译器wrap方式重载,但这块只能对可执行文件进行重载,不能实现glibc重载,这里所说的LD_PRELOAD是不是也只是针对可执行文件进行重载不能实现像动态库重载,如果是某个glibc中的函数使用malloc,这种方案是不是不能进行重载的;
作者回复: 文中的这种做法就是重载了glibc中的free函数。你可以自己动手试一下哦。
2021-11-1821 - 流浪地球请问老师,tcmalloc的线程本地缓存会不会导致相同的一份代码产生的进程,分配的虚拟内存空间会大一些呢?看描述像是增加预分配了一些空间
作者回复: 首先回答你的问题是,不会的。但我不理解你为什么会有这种误解,我怀疑你是哪个概念理解错了才会这样提问的。建议加微信群详细交流。
2021-11-174 - 骨汤鸡蛋面void* p1 = malloc(16); free(p1) free的时候,根据参数知道从地址p1开始free,那如何知道free 16个字节呢?2022-07-1111
- 会爆炸的小米Note老师好!mmap是相当于只修改了页表项,把相应页面的页表项修改成已分配未缓存的状态,然后在访问的时候通过缺页中断加载到物理内存中吗? 第一节课中吊打面试官的部分中说通过mmap构建映射后通过遍历访问才能让内存commit 请教下老师有什么高效的方法来进行访问吗2022-03-061
- 佳伦malloc通过mmap从操作系统申请一块比较大的内存再精细化管理,但是mmap申请到的内存对于操作系统来说,也需要伙伴算法来管理。所以,内存管理经历了好几个层面,操作系统层面、用户层面,在硬件层可能还有类似的管理方法。所以套了这么多层效率肯定会受影响2022-03-051