话说团队的兄弟有一天问我,为啥咱唯一的一个服务器,内存都用完了,我还想在上面测性能呢。我一听,第一反应:不可能!我说你胡扯呢吧,咱那可是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内存相关好文(转)的更多相关文章

  1. linux内存基础知识和相关调优方案

    内存是计算机中重要的部件之中的一个.它是与CPU进行沟通的桥梁. 计算机中全部程序的执行都是在内存中进行的.因此内存的性能对计算机的影响很大.内存作用是用于临时存放CPU中的运算数据,以及与硬盘等外部 ...

  2. (笔记)Linux内核中内存相关的操作函数

    linux内核中内存相关的操作函数 1.kmalloc()/kfree() static __always_inline void *kmalloc(size_t size, gfp_t flags) ...

  3. Linux内存中的Cache真的能被回收么?

    在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: [root@tencent64 ~]# free       ...

  4. linux 内存管理——内核的shmall 和shmmax 参数

    内核的 shmall 和 shmmax 参数 SHMMAX= 配置了最大的内存segment的大小 ------>这个设置的比SGA_MAX_SIZE大比较好. SHMMIN= 最小的内存seg ...

  5. Cgroup - Linux 内存资源管理

    Hi ,我是 Zorro .这是我的微博地址,我会不定期在这里更新文章,如果你有兴趣,可以来关注我呦. 另外,我的其他联系方式: Email: mini.jerry@gmail.com QQ: 300 ...

  6. 《嵌入式Linux内存使用与性能优化》笔记

    这本书有两个关切点:系统内存(用户层)和性能优化. 这本书和Brendan Gregg的<Systems Performance>相比,无论是技术层次还是更高的理论都有较大差距.但是这不影 ...

  7. Linux内存管理专题

    Linux的内存管理涉及到的内容非常庞杂,而且与内核的方方面面耦合在一起,想要理解透彻非常困难. 在开始学习之前进行了一些准备工作<如何展开Linux Memory Management学习?& ...

  8. Linux内存描述之高端内存--Linux内存管理(五)

    1. 内核空间和用户空间 过去,CPU的地址总线只有32位, 32的地址总线无论是从逻辑上还是从物理上都只能描述4G的地址空间(232=4Gbit),在物理上理论上最多拥有4G内存(除了IO地址空间, ...

  9. Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)

    专题:Linux内存管理专题 关键词:slub_debug.kmemleak.kasan.oob.Redzone.Padding. Linux常见的内存访问错误有: 越界访问(out of bound ...

随机推荐

  1. 软件工程 作业part1

    自我介绍 老师您好,我叫宋雨,本科在长春理工大学,专业是计算机科学与技术. 1.回想一下你曾经对计算机专业的畅想:当初你是如何做出选择计算机专业的决定?你认为过去接触的课程是否符合你对计算机专业的期待 ...

  2. 新人学PHP,认为手动搭建环境而苦恼吗?这篇文章告诉你多简单!

    本教程适用于初学PHP,想了解手动搭建PHP环境的童鞋. 一键环境和高手勿喷. 本教程以下列版本软件为例: 所需软件目录 我在这里的目录结构是(个人习惯) 安装与配置 apache 双击安装Apach ...

  3. iOS关于setContentOffset的一些细节问题

    在UIScrollView,setContentOffset方法的功能是跳转到你指定内容的坐标, setContentOffset有两种方法:setContentOffset:和setContentO ...

  4. erlang+thrift配合开发

    I  think, thrift is a  tcp/ip based Client-Server architecture multi-languages supported RPC framewo ...

  5. 在vue项目中使用monaco-editor

    monaco-editor: https://github.com/Microsoft/monaco-editor 在ESM中的使用官方也有对应文档:https://github.com/Micros ...

  6. centos设置时间同步

    1.安装ntpdate #yum install ntpdate   2. #cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #ntpdate ...

  7. Microsoft Edge goes Chromium

    Microsoft Edge goes Chromium https://techcrunch.com/2018/12/06/microsoft-edge-goes-chromium-and-maco ...

  8. BZOJ 1821 部落划分(二分+并查集)

    答案是具有单调性的. 因为最近的两个部落的距离为mid,所以要是有两个野人的距离<mid,则他们一定是一个部落的. 用并查集维护各联通块,如果最后的联通块个数>=k,那么mid还可以再小点 ...

  9. Codeforces Round #510 Div. 2 Virtual Participate记

    这场打的顺手到不敢相信.如果不是vp的话估计肯定打不到这个成绩. A:最大显然,最小的话每次暴力给最小的+1. #include<iostream> #include<cstdio& ...

  10. [Violet]天使玩偶

    description Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅凭一点模糊的记忆来寻找它. 我们把 ...