话说团队的兄弟有一天问我,为啥咱唯一的一个服务器,内存都用完了,我还想在上面测性能呢。我一听,第一反应:不可能!我说你胡扯呢吧,咱那可是16G的一个物理机,上面就跑了git服务器,怎么可能把内存吃完了呢。他撇了撇嘴:不信自己上去看。
既然这么说了,我便远程登上去瞅瞅吧。第一想到的就是top命令,于是,敲了top,得到了以下的截图:
就剩下3个G了(这个还是多的,当天就剩600多M free了),确实有些反常,shift+m看一下内存占用最高的进程是啥,得到以下的截图:
看到排名第一的是mysqld,占到了11.9%(%MEM)即1.8G(RES)的物理内存;排名第二的是java,只有6.5% 1.0G的物理内存(RES是指物理内存,下面详细说明);第三就只有0.1%,这把大头加一下,才用了3G内存,总共16个G呢,剩下10个G让谁吃了?
看到这儿,我无言以对了,不是我理解错了,就是top工具撒谎了。赶紧开始google相关的东西,第一个得到的就是另外一个查看内存的工具:free:
free这个工具是专门用来显示当前物理内存以及虚拟内存情况的,后面的参数-m是让工具以MB为单位来显示数据,从这里可以非常清楚的看到,Mem的free是3856MB,确实和top显示的一样,看来top工具没有撒谎,一定是我们理解错什么了。
继续google,逐渐理解到了这样一件事儿。我们从free工具显示的结果中可以看到这么一行:-/+ buffers/cache,这里显示free为12367MB,这是什么意思呢。
这里就必须说一下linux设计内存管理时的一个想法了。linux认为,我们的内存在系统启动之后,大部分情况下都会是空闲的。既然是空闲的,那linux就琢磨,不用白不用啊,我先用它干点儿啥,等你正儿八经要用的时候我再还给你。于是,linux就开始把这部分的空闲内存都先拿过来用着,干吗用呢?linux琢磨,你硬盘不是慢么,咱就想办法把这部分内存用作硬盘的一个缓存,这样,你要访问什么文件的时候我先给你加载到内存中缓存着(比如一些程序执行的文件以及一些共享库等,这在linux内称为显式的Pages;对应的隐式的Pages指的是为运行程序保留的数据、栈空间等),以后每次你访问的时候我都从这部分内存中给你拿,不去和硬盘打交道,这速度不就大大的快了;当一个进程真正想用内存的时候,linux就会从它占用的这些缓存内存中空闲的部分分配需要的大小给你,不用担心linux一直占着不给。
知道了上面这个,就好解释free工具中那个-/+ buffers/cache行的意思了。其实这一行所表示的free才是真正的物理内存当前的空闲值,第一行Mem中的free只是我们实际的内存-内核占用-实际使用-linux拿跑做缓存后所剩下的值。另外要想判断是不是真的内存用光了,通过判断Swap也可以知道当前物理内存是否用完了。
另外,这里还有一个小细节需要提一下,free工具中Mem的total值是15900MB(和top一样),远不是我说的16GB,这是因为,其中一部分被linux内核占用了,linux内核是无法swap out的,所以这部分内存是永远不会free。
说回刚才的这个被linux占用的cache来。从我google的结果来看,其实linux占用的这个cache也不是一下全部用掉了,它也有已经被使用和free的部分,被使用的部分主要是上面提到的当前进程相关联的一些程序文件或者共享库等,还有为进程保留的栈空间和运行时数据的空间,这两个分别被称为显式的Pages(也称为文件缓存)和隐式的Pages。那么现在问题来了,如果cache中全部被这些数据占有了之后,我们再想分配内存的时候该怎么办呢?此时就得分两步来聊了:
对于显式Pages来说,既然它是文件缓存,顾名思义,它是有硬盘的文件做备份的,即使linux系统在内存不够的情况下把它从内存中清理出去了(注意不是swap out),那么我们在需要的时候还可以访问硬盘把这些数据读回来使用(可能就是会慢一些),当然如果有swap空间的情况下还是会先swap out;
对于隐式Pages来说就不好办了,因为这个如果从内存中清理出去了,就回不来了,所以不能清理,只能把它临时的swap out出去,需要的时候在swap回来;那么,当出现内存不够用且swap空间也不够用的情况时,linux就无法将隐式的Pages swap out出去,此时OOM-killer(out of memory killer)就开始工作,将一些占内存的进程干掉来释放内存给其它进程;
这个时候又有问题来了,当内存不够用的时候,到底是清理显式的Pages还是swap out隐式的Pages呢?从linux kernel 2.6.28之后开始,linux对两种Pages做了权重值来做处理这件事情:默认情况下,权重值的总值为200,系统有一个配置:vm.swappiness,用来指定隐式Pages的权重,这个值默认是60,那么对于显式的Pages来说,它的权重就是200-vm.swappiness,默认情况下就是140;当linux需要swap out内存的时候,首先处理的就是权重高的,即显式的Pages;
当我们把vm.swappiness设置成0时,linux就会尽可能的保证隐式Pages不会被swap out出去,这种设置对于需要自己做缓存的系统有非常大的性能提升;
将vm.swappiness设置成100,可以提高I/O密集型系统的性能,防止显式Pages的文件缓存被清理出去;
vm.swappiness可以通过cat /proc/sys/vm/swappiness来查看;通过sysctl -w vm.swappiness=N 或者 echo 30 >/proc/sys/vm/swappiness来修改;也可以通过修改/etc/sysctl.conf里的vm.swappiness来在linux启动时就修改。
了解了上面这些,使我突然明白了一个东西,就是在linux中(windows不知道),不设置swap空间其实不能对系统的性能有提升,反而可能下降;因为linux系统不会因为没有swap空间就不清理内存的Pages,只是当没有swap空间的时候,linux系统可能要优先处理显式的Pages,因为它有硬盘文件做备份,此时性能同样会下降;
最后,补充一下top工具显示出来的内存相关项目的意思,主要有以下几个:
VIRT:这个指的是一个进程占用内存的虚拟大小,换句话说就是该进程当前实际访问的内存大小。具体来说,除了进程自己占用的物理内存外,还包括映射给它的内存(比如X Server需要的显卡内存),硬盘的文件在内存中的映射所需的大小(大部分是一些共享库),已经swap out的大小,以及和其它进程共享的内存等;
RES:这个刚才说过了,是该进程实际占用的物理内存大小,它不包含已经swap out的大小,这个值也是后面%MEM测量所需的值,当然,这个值一定会小于上面的VIRT;
SHR:这个值得是在VIRT中,实际的共享内存和共享库所占用的内存大小,这里需要注意的是,一半一个进程只会使用某个共享库的一部分代码,但是在VIRT和SHR中,整个共享库在内存中的映射都会计算进来,但是只有实际使用的会计算到RES中。
转载:http://blog.licess.com/linux-memory/
参考文章:
Overview of memory management: http://www.linuxhowtos.org/System/Linux%20Memory%20Management.htm
Why is swappiness set to 60 by default?: http://unix.stackexchange.com/questions/88693/why-is-swappiness-set-to-60-by-default
- linux内存基础知识和相关调优方案
内存是计算机中重要的部件之中的一个.它是与CPU进行沟通的桥梁. 计算机中全部程序的执行都是在内存中进行的.因此内存的性能对计算机的影响很大.内存作用是用于临时存放CPU中的运算数据,以及与硬盘等外部 ...
- (笔记)Linux内核中内存相关的操作函数
linux内核中内存相关的操作函数 1.kmalloc()/kfree() static __always_inline void *kmalloc(size_t size, gfp_t flags) ...
- Linux内存中的Cache真的能被回收么?
在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: [root@tencent64 ~]# free ...
- linux 内存管理——内核的shmall 和shmmax 参数
内核的 shmall 和 shmmax 参数 SHMMAX= 配置了最大的内存segment的大小 ------>这个设置的比SGA_MAX_SIZE大比较好. SHMMIN= 最小的内存seg ...
- Cgroup - Linux 内存资源管理
Hi ,我是 Zorro .这是我的微博地址,我会不定期在这里更新文章,如果你有兴趣,可以来关注我呦. 另外,我的其他联系方式: Email: mini.jerry@gmail.com QQ: 300 ...
- 《嵌入式Linux内存使用与性能优化》笔记
这本书有两个关切点:系统内存(用户层)和性能优化. 这本书和Brendan Gregg的<Systems Performance>相比,无论是技术层次还是更高的理论都有较大差距.但是这不影 ...
- Linux内存管理专题
Linux的内存管理涉及到的内容非常庞杂,而且与内核的方方面面耦合在一起,想要理解透彻非常困难. 在开始学习之前进行了一些准备工作<如何展开Linux Memory Management学习?& ...
- Linux内存描述之高端内存--Linux内存管理(五)
1. 内核空间和用户空间 过去,CPU的地址总线只有32位, 32的地址总线无论是从逻辑上还是从物理上都只能描述4G的地址空间(232=4Gbit),在物理上理论上最多拥有4G内存(除了IO地址空间, ...
- Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)
专题:Linux内存管理专题 关键词:slub_debug.kmemleak.kasan.oob.Redzone.Padding. Linux常见的内存访问错误有: 越界访问(out of bound ...
随机推荐
- df -h 卡住
mount 检查是否有挂载nfs的分区 网络挂载 如果有请umount -l /相应目录 umount -l 10.74.82.205:/letv/fet/nfs ...
- 11.24Daily Scrum
人员 任务分配完成情况 明天任务分配 王皓南 实现网页上视频浏览的功能.研究相关的代码和功能.990 测试 申开亮 实现网页上视频浏览的功能.研究相关的代码和功能.991 测试 王宇杰 负责后台代码测 ...
- Java中的线程同步
Java 中的线程同步问题: 1. 线程同步: 对于访问同一份资源的多个线程之间, 来进行协调的这个东西. 2. 同步方法: 当某个对象调用了同步方法时, 该对象上的其它同步方法必须等待该同步方法执行 ...
- spring框架(1)— 依赖注入
依赖注入 spring核心容器就是一个超级大工厂,所以的对象(数据源.hibernate SessionFactory等基础性资源)都会被当做spring核心容器的管理对象——spring把容器中的一 ...
- Spring Boot(二)配置分析
回顾一下采用SSM开发项目时,项目中会存在多个配置文件,比如web.xml,配置Spring相关的applicationContext-springmvc.xml, applicationContex ...
- 3dContactPointAnnotationTool开发日志(二十)
为了使工具更人性化,我又在每个status的text上绑了个可以拖拽实现值改变的脚本,但是不知道为啥rotx那个值越过+-90范围后连续修改就会产生抖动的现象,试了很多方法也没能弄好,不过实际用起 ...
- JavaScript:理解事件、事件处理函数、钩子函数、回调函数
详情请点击 http://www.jianshu.com/p/a0c580ed3432
- C的强制转换和C++的强制转换(转)
C的强制转换: (type)<expression> 其中,type为类型描述符,如int,float等.<expression>为表达式.经强制类型转换运算符运算后,返回一个 ...
- 【bzoj5107】[CodePlus2017]找爸爸 dp
题目描述 给出两个基因串,你需要在其中插入任意个空格,使得两个串长度相同.如果两个串的某同一位置都是字母则获得某给定收益,对于每个串的每个长度为k的连续空格段要付出a(k-1)+b的损失.求最大净收益 ...
- 【bzoj1705】[Usaco2007 Nov]Telephone Wire 架设电话线 dp
题目描述 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线. 新的电话线架设在已有的N(2 <= N < ...