内存管理
文章平均质量分 83
阐述一些内存管理的机制和源码分析,各个分配器的使用和对比性能。
guoguangwu
这个作者很懒,什么都没留下…
展开
-
golang context 内存大小
golang context 内存大小原创 2022-10-31 14:59:16 · 386 阅读 · 0 评论 -
linux mlock 不生效
linux mlock 不生效原创 2022-06-18 15:21:38 · 652 阅读 · 0 评论 -
linux内存管理-系统调用mmap()
一个进程可以通过系统调用mmap,将一个已打开文件的内容映射到它的用户空间,其用户界面为:void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);参数fd代表着一个已打开文件,offset为文件中的起点,而addr为映射到用户空间中的起始地址,length则为长度。还有两个参数prot和flags,前者用于对映射区间的访问模式,如可写、可执行等等,后者则用于原创 2021-10-24 10:21:33 · 2777 阅读 · 0 评论 -
linux内存管理-系统调用brk()
尽管可见度不高,brk也许是最常使用的系统调用了,用户进程通过它向内核申请空间。人们常常并不意识到在调用brk,原因在于很少有人会直接使用系统调用brk向系统申请空间,而总是通过像malloc一类的C语言库函数(或语言成分,如C++中的new)间接地调用brk。如果把malloc想象成零售,brk则是批发。库函数malloc为用户进程(malloc本身就是该进程的一部分)维持一个小仓库,当进程需要使用更多的内存空间时就向小仓库要,小仓库中存量不足时就通过brk向内核批发。前面讲过,每个进程拥有3GB字节原创 2021-10-23 19:30:21 · 6443 阅读 · 2 评论 -
linux内存管理-外部设备存储空间的地址映射
任何系统都免不了要由输入、输出,所以对外部设备的访问是CPU设计中的一个重要问题。一般来说,对外部设备的访问有两种不同的形式,一种叫做内存映射式(memory mapped),另一种叫IO映射式(I/O mapped)。在采用内存映射方式的CPU中,外部设备的存储单元,如控制寄存器、状态寄存器、数据寄存器等等,是作为内存的一部分出现在系统中的。CPU可以向访问一个内存单元一样的访问外部设备的存储单元,所以不需要专门设立用于外设I/O的指令。从前的PDP-11、后来的M68K、PowerPC等CPU都采用这种原创 2021-10-23 16:18:38 · 1349 阅读 · 0 评论 -
linux内存管理-内核缓冲区的管理
可想而知,内核在运行中常常会需要使用一些缓冲区。例如,当要建立一个新的进程时就要增加一个task_struct结构,而当进程撤销时就要释放本进程的task结构。这些小块存储空间的使用并不局限于某一个子程序,否则就可以作为整个子程序的局部变量而使用堆栈空间了。另外,这些小块存储空间又是动态变化的,不像用于内存管理的page结构那样,有多大的内存就有多少个page结构,构成一个静态的阵列。由于事先根本无法预测运行中各种不同数据结构对缓冲区的需求,不适合为每一种可能用到的数据结构建立一个缓冲池,因为那样的话很可能原创 2021-10-22 21:40:03 · 1087 阅读 · 0 评论 -
linux内存管理-页面的换入
在i386 CPU将一个线性地址映射成物理地址的过程中,如果该地址的映射已经建立,但是发现相应页面表项或目录项中的P(present)标志位为0,则表明相应的物理页面不在内存中,从而无法完成本次内存访问。从理论上说,也许应该把这种情况称为受阻而不是失败,因为映射的关系毕竟已经建立,理应与尚未建立映射的情况有所区别,所以我们称为断开。但是,CPU的MMU硬件并不区分这两种不同的情况,只要P标志位为0就都认为是页面映射失败,CPU就会产生一次页面异常(page fault)。事实上,CPU在映射过程中首先看的就原创 2021-10-18 23:18:35 · 572 阅读 · 0 评论 -
linux内存管理-页面的定期换出
这个情景比较长,我们得有点耐心。为了避免总是在CPU忙碌的时候,也就是在缺页异常发生的时候,临时再来搜索可供换出的内存页面并加以换出,linux内核定期地检查并预先将若干页面换出,腾出空间,以减轻系统在缺页异常发生时的负担。当然,由于无法确定地预测页面的使用,即使这样做了也还是不能完全杜绝在缺页异常发生时内存内有空闲页面,而只好临时寻找可换出页面的可能。但是,这样毕竟可以减少其发生的概率。并且,通过选择适当的参数,例如每隔多久换出一次,每次换出多少页面,可以使得在缺页异常发生时必须临时寻找页面换出的情况原创 2021-10-12 23:18:45 · 654 阅读 · 0 评论 -
linux内存管理-物理页面的分配
前面的博客中曾经提到,当需要分配若干内存页面时,用于DMA的内存页面必须是连续的。其实,为便于管理,特别是处于对物理存储空间质地一致性的考虑,即使不是用于DMA的内存页面也是连续分配的。当一个进程需要分配若干连续的物理页面时,可以通过alloc_pages来完成。linux2.4.0内核版本的代码中有两个alloc_pages,一个是在mm/numa.c中,另一个在mm/page_alloc.c中,编译时根据所定义的条件编译选择CONFIG_DISCONTIGMEM决定取舍。为什么呢?这就是出于前面博客原创 2021-10-10 16:25:36 · 523 阅读 · 0 评论 -
linux内存管理-物理页面的使用与周转
除CPU之外,对于像linux这样的现代操作系统来说,物理存储页面可以说是最基本、最重要的资源了。物理存储页面在系统中的使用和周转就好像资金在企业中的使用和周转一样重要。因此,我们对此最后能有更多一些的了解。首先要澄清本系列博客中使用的几个术语。“虚存页面”,是指在虚拟地址空间中一个固定大小,边界与页面大小(4KB)对齐的区间及其内容。虚存页面最终要落实到,或者说要映射到某汇总物理存储介质上,那就是物理页面。根据具体介质的不同,一个物理页面可以再内存中,也可以在磁盘上。为了区分这两种情况,本博客将分别称原创 2021-10-10 11:37:21 · 524 阅读 · 0 评论 -
linux内存管理-用户堆栈的扩展
在上一情景中,我们游览参观了一次因越界访问而造成映射失败从而引起进程流产的过程。但是,我们也许会感到惊奇,越界访问有时是正常的。不过,这只是发生在一种情况下,现在我们就来看看当用户堆栈过小,但是因越界访问而因祸得福得以伸展的情景。在阅读本情景之前,我们应该温习一下前一个情景。假设在进程运行的过程中,已经用尽了为本进程分配的堆栈区间,也就是从堆栈的顶部开始(记住,堆栈是从上向下伸展的),已经到达了已经映射的堆栈区间的下沿。或者说,CPU中的堆栈指针%esp已经指向堆栈区间的起始地址。见下图:假原创 2021-10-07 17:46:05 · 736 阅读 · 0 评论 -
linux内存管理-越界访问
页式存储管理机制通过页面目录和页面表将每个线性地址(也可以称为虚拟地址)转换成物理地址。如果在这个过程中遇到某种阻碍而使CPU无法最终访问到相应的物理内存单元,映射就失败了。而当前的指令也就不能执行完成。此时CPU会产生一次页面出错(page fault)异常(也称缺页异常中断),进而执行预定的页面异常处理程序,使应用程序得以因映射失败而暂停的指令处开始恢复执行,或进行一些善后处理。这里所说的阻碍可以由以下几种情况:相应的页面目录项或页面表项为空,也就是该线性地址与物理地址的映射关系尚未建立,或者已经撤原创 2021-10-05 17:06:30 · 1154 阅读 · 0 评论 -
linux内存管理-几个重要的数据结构和函数
从硬件的角度来说,linux内核只要能为硬件准备好页面目录PGD、页面表PT以及全局段描述表GDT和局部段描述表LDT,并正确地甚至设置有关的寄存器,就完成了内存管理机制中地址映射部分的准备工作。虽然最终的目的是地址映射,但是实际上内核所需要做的管理工作却要复杂的多。在于内存管理有关的内核代码中,有几个数据结构是很重要的,这些数据结构及其使用构成了代码中内存管理的基本框架。页面目录PGD、中建目录PMD和页面表PT分别是由表项pgd_t、pmd_t记忆pte_t构成的数组,而这些表项又都是数据结构,定义如原创 2021-10-04 20:59:10 · 952 阅读 · 0 评论 -
linux内存管理-地址映射的全过程
linux内核采用页式存储管理。虚拟地址空间划分成固定大小的页面,由MMU在运行时将虚拟地址映射成(或者说变换成)某个物理内存页面中地址。与段式存储管理相比,页式存储管理有很多好处。首先,页面都是固定大小的,便于管理。更重要的是,当要将一部分屋里空间的内容换出到磁盘上的时候,在段式存储管理中要将整个段(通常都很大)都换出,而在页式存储管理中则是按页进行,效率显然要高得多。页式存储管理与段式存储罐所要求的硬件支持不同,一种CPU既然支持页式存储管理,就无需再支持段式存储管理。但是,i386的情况比较特殊,不管原创 2021-10-04 12:15:26 · 1978 阅读 · 0 评论 -
linux内存管理的基本框架
i386 CPU中的页式存储管理的基本思路是:通过页面目录和页面表分两个层次实现从线性地址到物理地址的映射。这种映射模式在大多数情况下可以节省页面表所占用的空间。因为大多是进程不会用到整个虚存空间,在虚存空间中通常都留有很大的空洞。采用两层的方式,只要一个目录项所对应的那部分空间是个空洞,就可以把该目录项设置成空,从而省下了与之对应的页面表(1024个页面描述项)。当地址的宽度为32位时,两层映射机制比较有效也比较合理。但是,当地址的宽度大于32位时,两层映射显得不尽合理,不够有效了。原创 2021-10-03 22:20:40 · 309 阅读 · 0 评论 -
使用valgrind 查看 jemalloc tcmalloc ptmalloc 在auditd中的性能对比
目前在使用Linux提供的auditd的审计功能。发现在大量的系统调用的情况下,性能上不去。使用valgrind对其进行性能分析。目前对auditd进行分段分析性能,关闭写文件write_logs=no (/etc/audit/auditd.conf),接收到kauditd从netlink发过来的数据后,关闭处理完之后,不转发给/sbin/audispd, 实现方式是在src/auditd...原创 2019-08-05 19:48:24 · 649 阅读 · 0 评论 -
TCMalloc : Thread-Caching Malloc (翻译)
MotivationTCMalloc is faster than the glibc 2.3 malloc (available as a separate library called ptmalloc2) and other mallocs that I have tested. ptmalloc2 takes approximately 300 nanoseconds to execu...原创 2019-03-29 12:26:26 · 360 阅读 · 0 评论