iis 7.0 网站配置,大气企业网站源码php,提高网页加载速度的方式,设计网官方网站linux内存分配管理一、前言作为从事与C/C程序开发人员#xff0c;我们一直需要很好的管理内存#xff0c;申请和释放#xff1b;可能很多只知道使用malloc、new去申请#xff0c;使用free、delete去释放#xff0c;但是#xff0c;去根究其内部的原理#xff0c;可能就不… linux内存分配管理一、前言 作为从事与C/C程序开发人员我们一直需要很好的管理内存申请和释放可能很多只知道使用malloc、new去申请使用free、delete去释放但是去根究其内部的原理可能就不是很清楚了 这里主要对linux平台的内存管理进行一下总结和梳理二、内存申请释放Linux虚拟内存管理相关概念请移步至详解linux虚拟内存原理这里主要说说的是我们的内存是怎么申请的在C/C中使用malloc进行内存分配C使用的new但是其底层也是使用malloc在系统调用上面一般使用的是brk()和mmap()函数我们说一说这两个函数的使用场景brk():当内存分配使用小于128K对于小于128K的小块内存系统会使用 brk() 来分配也就是通过移动堆顶的位置来分配内存。这些内存释放后并不会立刻归还系统而是被缓存起来这样就可以重复使用。**注**使用brk()分配内存时只分配虚拟空间不对应物理内存只有第一次读/写数据时引起内核缺页中断内核才分配对应的物理内存然后在虚拟地址上建立映射关系回收内存申请内存使用完毕之后内存并不是真正的释放掉了而是只回推了**_edata**指针内存可以被重复利用brk分配的内存需要等到高地址内存释放以后才能释放brk分配的内存需要等到高地址内存释放以后才能释放所以会产生内存碎片但是当最高地址空间超过了128k就会执行trim(内存紧缩)操作mmap()大于128K大块内存(大于 128K)则直接使用内存映射 mmap() 来分配也就是在文件映射段找一块空闲内存分配出去。注意这个和brk()是一样的只有第一次使用的时候才会真正分配物理内存回收内存mmap回收内存时是直接释放归还不会进行重复利用所以这种会导致每次 mmap 都会发生缺页异常。在内存工作繁忙时频繁的内存分配会导致大量的缺页异常使内核的管理负担增大。这也是 malloc 只对大块内存使用 mmap 的原因。参考Linux内存分配小结--malloc、brk、mmap三、linux内存管理伙伴算法定义由一个母实体分成的两个各方面属性一致的两个子实体这两个子实体就处于伙伴关系。在操作系统分配内存的过程中一个内存块常常被分成两个大小相等的内存块这两个大小相等的内存块就处于伙伴关系伙伴系统的宗旨就是用最小的内存块来满足内核的对于内存的请求。在最初只有一个块也就是整个内存假如为1M大小而允许的最小块为64K那么当我们申请一块200K大小的内存时就要先将1M的块分裂成两等分各为512K这两分之间的关系就称为伙伴然后再将第一个512K的内存块分裂成两等分各位256K将第一个256K的内存块分配给内存这样就是一个分配的过程伙伴系统特点1)两个块大小相同2)两个块地址连续3)两个块必须是同一个大块中分离出来的作用伙伴系统是以page为单位进行操作的一般管理的是大内存分配具体详细参考Linux伙伴系统(一)--伙伴系统的概述slab 分配器linux内核中会采用伙伴算法进行内存分配管理但是分配的内存区是以页框为基本单位的。对于内核中小块连续内存的请求比 如说几个字节或者几百个字节如果依然分配一个页框来来满足该请求这样的话就会有内存碎片产生定义slab分配器中用到了对象这个概念所谓对象就是内核中的数据结构以及对该数据结构进行创建和撤销的操作。它的基本思想是将内核中经常使用的对象 放到高速缓存中并且由系统保持为初始的可利用状态。比如进程描述符内核中会频繁对此数据进行申请和释放。当一个新进程创建时内核会直接从slab分 配器的高速缓存中获取一个已经初始化了的对象当进程结束时该结构所占的页框并不被释放而是重新返回slab分配器中。如果没有基于对象的slab分 配器内核将花费更多的时间去分配、初始化以及释放一个对象。slab分配器有以下三个基本目标1.减少伙伴算法在分配小块连续内存时所产生的内部碎片2.将频繁使用的对象缓存起来减少分配、初始化和释放对象的时间开销。3.通过着色技术调整对象以更好的使用硬件高速缓存参考Linux内存管理中的slab分配器作用高速缓存分配小块内存具体详细参考【Linux 内核】内存管理(三)slab分配器说明这是linux中比较重要的两个内存管理的方式我对这块也只是了解状态并没有深入去研究这里只是简单概括一下以后有时间细细研究一下现在大概知道这个原理和概念就行了四、回收内存那么上面说了内存分配相关的内容那么如果内存出现了紧张那系统自己会怎么办其实linux自己也做了一套机制来进行内存回收回收缓存比如使用 LRU(Least Recently Used)算法回收最近使用最少的内存页面原理LRU(Least recently used最近最少使用)算法根据数据的历史访问记录来进行淘汰数据其核心思想是“如果数据最近被访问过那么将来被访问的几率也更高”。实现最常见的实现是使用一个链表保存缓存数据详细算法实现如下新数据插入到链表头部每当缓存命中(即缓存数据被访问)则将数据移到链表头部当链表满的时候将链表尾部的数据丢弃。分析【命中率】当存在热点数据时LRU的效率很好但偶发性的、周期性的批量操作会导致LRU命中率急剧下降缓存污染情况比较严重。【复杂度】实现简单。【代价】命中时需要遍历链表找到命中的数据块索引然后需要将数据移到头部。Swap回收不常访问的内存把不常用的内存通过交换分区直接写到磁盘中回收不常访问的内存时会用到交换分区也称为Swap。Swap 其实就是把一块磁盘空间当成内存来用。它可以把进程暂时不用的数据存储到磁盘中(这个过程称为换出)当进程访问这些内存时再从磁盘读取这些数据到内存中(这个过程称为换入)Swap 把系统的可用内存变大了。通常只有在内存不足时才会发生 Swap 交换。相对于内存来说磁盘读写的速度很慢所以Swap 会导致严重的内存性能问题。OOM杀死进程内存紧张时系统还会通过 OOM(Out of Memory)直接杀掉占用大量内存的进程。oom内核的一种保护机制它表示“内存用完了”。它监控进程的内存使用情况并且使用 oom_score 为每个进程的内存使用情况进行评分一个进程消耗的内存越大oom_score 就越大一个进程运行占用的 CPU 越多oom_score 就越小。这样进程的 oom_score 越大代表消耗的内存越多也就越容易被 OOM 杀死从而可以更好保护系统。当然为了实际工作的需要管理员可以通过 /proc 文件系统手动设置进程的 oom_adj 从而调整进程的 oom_score。oom_adj 的范围是 [-17, 15]数值越大表示进程越容易被 OOM 杀死数值越小表示进程越不容易被 OOM 杀死其中 -17 表示禁止 OOM。五、查看内存命令一般我们会使用free来查看内存当然我们还可以使用ps/top等命令先看一下free命令吧rootiZuf67on1pthsuih96udyfZ:~/# free total used free shared buff/cache availableMem: 953036 388052 65808 2860 499176 377200Swap: 0 0 0简单的看一下每个字段的意义total 是总内存大小used 是已使用内存的大小包含了共享内存free 是未使用内存的大小shared 是共享内存的大小buff/cache 是缓存和缓冲区的大小available 是新进程可用内存的大小。这就是大概是linux内存相关的一些知识点这里写的比较乱相当于做个笔记了~~~想了解学习更多C后台服务器方面的知识请关注微信公众号CPP后台服务器开发扫码CPP后台服务器开发转载是一种动力 分享是一种美德