上一篇文章说的硬盘。就写一下。更加重要的东西。在手机上面是RAM。机器是memory。内存是按照字节编址。每个地址的存储单元可以存放8bit的数据、cpu 通过内存地址获取一条指令和数据。内存溢出out-of-memory killer 负责终止使用内存过多的进程。详细的细节请查看/var/log/messages文件。建立索引常会发生这种情况。管理员可以限制服务不被OOM。数据的预热。压力测定时。自动化测试。灰度发布。监控采集。
每一个内存都是进程产生的。到底什么是内存。其实进程是有自己的虚拟地址空间。虚拟地址空间对应的才是内存。
虚拟地址对应的物理地址不在物理内存中。产生缺页中断、真正分配物理地址,同时更新进程页表
如果物理内存存在,但是被耗尽。则根据内存替换算法淘汰部门页面至物理磁盘中。
进程的虚拟地址空间是有几个概念。如下图:
内存分配的原理:
从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)。
1、小于128k。brk是将数据段(.data)的最高地址指针_edata往高地址推;
2、大于128K。mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存。
这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系
1)查看linux虚拟地址空间和物理地址
cat /proc/cpuinfo
64位的系统。是2^48虚拟地址空间是48、40位是物理地址
2)查看进程缺页中断次数(虚拟地址对应的物理地址不在物理内存中。则产生缺页中断)
ps -o maj_flt,min_flt -p pid 查看写数据模块。能看到大量的缺页中断
发成缺页中断后,执行了那些操作?
当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作:
1、检查要访问的虚拟地址是否合法
2、查找/分配一个物理页
3、填充物理页内容(读取磁盘,或者直接置0,或者啥也不干)
4、建立映射关系(虚拟地址到物理地址)
重新执行发生缺页中断的那条指令
如果第3步,需要读取磁盘,那么这次缺页中断就是majflt,否则就是minflt。
3 )程序退出了,内存会释放吗?
答:程序退出了,内存就会被系统慢慢释放掉,系统有内存清理机制,
就算是new出来的程序中没有释放,程序停止后也会释放的。但是new出来的对象没用后,程序员都应该手动释放掉,像C语言如果不释放,长时间运行必然会有内存不足。Java程序虽然jvm有垃圾回收机制,但是如果超出了垃圾回收机制的范围也会经常出现内存不足
4 )内存溢出和内存泄漏
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak会最终会导致out of memory!
内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出。
5)内存监控项
计算方法:读取/proc/meminfo 中的内容,其中的mem.memfree是free+buffers+cached,mem.memused=mem.memtotal-mem.memfree。用户具体可以参考free命令的输出和帮助文档来理解
mem.memtotal:内存总大小
mem.memused:使用了多少内存
mem.memused.percent:使用的内存占比
mem.memfree
mem.memfree.percent
mem.swaptotal:swap总大小
mem.swapused:使用了多少swap
mem.swapused.percent:使用的swap的占比
mem.swapfree
mem.swapfree.percent
6)查看当前机器内存信息:
#dmidecode | grep -A16 "Memory Device$"
查看每个内存大小
#dmidecode | grep -A16 "Memory Device$" | grep -i "Size" | grep -v "No"
top -d 1
free -m
7)性能分析的目的
1、找出系统性能瓶颈(包括硬件瓶颈和软件瓶颈);
2、提供性能优化的方案(升级硬件?改进系统系统结构?);
3、达到合理的硬件和软件配置;
4、使系统资源使用达到最大的平衡。(一般情况下系统良好运行的时候恰恰各项资源达到了一个平衡体,任何一项资源的过渡使用都会造成平衡体系破坏,从而造成系统负载极高或者响应迟缓。比如CPU过渡使用会造成大量进程等待CPU资源,系统响应变慢,等待会造成进程数增加,进程增加又会造成内存使用增加,内存耗尽又会造成虚拟内存使用,使用虚拟内存又会造成磁盘IO增加和CPU开销增加)
8)影响性能的因素
1、内存(物理内存不够时会使用交换内存,使用swap会带来磁盘I0和cpu的开销)
2、使用常见的性能分析工具(vmstat、top、free、iostat等)
9)vmstat详细介绍
vmstat是一个很全面的性能分析工具,可以观察到系统的进程状态、内存使用、虚拟内存使用、磁盘的IO、中断、上下文切换、CPU使用等。对于 Linux 的性能分析,100%理解 vmstat 输出内容的含义,并能灵活应用,那对系统性能分析的能力就算是基本掌握了。
下面是vmstat命令的输出结果: vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 191908 188428 1259328 0 0 10 27 61 92 0 1 98 0 0
0 0 0 191892 188428 1259360 0 0 0 0 117 226 0 0 100 0 0
对输出解释如下:
1、procs
a.r列表示运行和等待CPU时间片的进程数,这个值如果长期大于系统CPU个数,就说明CPU资源不足,可以考虑增加CPU;
b.b列表示在等待资源的进程数,比如正在等待I/O或者内存交换等。
2、memory
a.swpd列表示切换到内存交换区的内存数量(以KB为单位)。如果swpd的值不为0或者比较大,而且si、so的值长期为0,那么这种情况一般不用担心,不会影响系统性能;
b.free列表示当前空闲的物理内存数量(以KB为单位);
c.buff列表示buffers cache的内存数量,一般对块设备的读写才需要缓冲;
d.cache列表示page cached的内存数量,一般作文件系统的cached,频繁访问的文件都会被cached。如果cached值较大,就说明cached文件数较多。如果此时IO中的bi比较小,就说明文件系统效率比较好。
3、swap
a.si列表示由磁盘调入内存,也就是内存进入内存交换区的数量;
b.so列表示由内存调入磁盘,也就是内存交换区进入内存的数量
c.一般情况下,si、so的值都为0,如果si、so的值长期不为0,则表示系统内存不足,需要考虑是否增加系统内存。
4、IO
a.bi列表示从块设备读入的数据总量(即读磁盘,单位KB/秒)
b.bo列表示写入到块设备的数据总量(即写磁盘,单位KB/秒)
这里设置的bi+bo参考值为1000,如果超过1000,而且wa值比较大,则表示系统磁盘IO性能瓶颈。
5、system
a.in列表示在某一时间间隔中观察到的每秒设备中断数;
b.cs列表示每秒产生的上下文切换次数。
上面这两个值越大,会看到内核消耗的CPU时间就越多。
6、CPU
a.us列显示了用户进程消耗CPU的时间百分比。us的值比较高时,说明用户进程消耗的CPU时间多,如果长期大于50%,需要考虑优化程序啥的。
b.sy列显示了内核进程消耗CPU的时间百分比。sy的值比较高时,就说明内核消耗的CPU时间多;如果us+sy超过80%,就说明CPU的资源存在不足。
c.id列显示了CPU处在空闲状态的时间百分比;
d.wa列表示IO等待所占的CPU时间百分比。wa值越高,说明IO等待越严重。如果wa值超过20%,说明IO等待严重。
e.st列一般不关注,虚拟机占用的时间百分比。 (Linux 2.6.11)
10)写内存监控项篇就一定要写的swap
1、先说说什么是swap分区以及它的作用?
Swap分区,即交换区,Swap空间的作用可简单描述为:当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序 使用。
那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap空间中,等到那些程序要运行时,再从Swap中恢 复保存的数据到内存中。
这样,系统总是在物理内存不够时,才进行Swap交换。 其实,Swap的调整对Linux服务器,特别是Web服务器的性能至关重要。通过调整Swap,有时可以越过系统性能瓶颈,节省系统升级费用。
分配太多的Swap空间会浪费磁盘空间,而Swap空间太少,则系统会发生错误。
如果系统的物理内存用光了,系统就会跑得很慢,但仍能运行;如果Swap空间用光了,那么系统就会发生错误。
例如,Web服务器能根据不同的请求数量衍生 出多个服务进程(或线程),如果Swap空间用完,则服务进程无法启动,通常会出现“application is out of memory”的错误,严重时会造成服务进程的死锁。
因此Swap空间的分配是很重要的。
通常情况下,Swap空间应大于或等于物理内存的大小,最小不应小于64M,通常Swap空间的大小应是物理内存的2-2.5倍。
但根据不同的应用,应有不同的配置:如果是小的桌面系统,则只需要较小的Swap空间,而大的服务器系统则视情况不同需要不同大小的Swap空间。
特别是数据库服务器和Web服 务器,随着访问量的增加,对Swap空间的要求也会增加,具体配置参见各服务器产品的说明。
另外,Swap分区的数量对性能也有很大的影响。因为Swap交换的操作是磁盘IO的操作,如果有多个Swap交换区,Swap空间的分配会以轮流的方式 操作于所有的Swap,这样会大大均衡IO的负载,加快Swap交换的速度。
如果只有一个交换区,所有的交换操作会使交换区变得很忙,使系统大多数时间处 于等待状态,效率很低。用性能监视工具就会发现,此时的CPU并不很忙,而系统却慢。这说明,瓶颈在IO上,依靠提高CPU的速度是解决不了问题的
看了这么多,再想想有时在论坛中的有的人说的他们的内存很大而没必要使用swap分区,别人10台机器能解决的问题,我们若合理使用swap分区,使用8台机器能解决的问题,何乐而不为呢 ?
下面说说swap分区的优化:
1.首先,做到尽量使用分区而非文件,记住除非万不得已
2.当然也可能是空间太小,那么就自己添加swap分区
3.特别注意的的是使用分区号较小的分区
4.分布到不同设备上可以实现轮循
5.若真的有多个swap分区,也可以指定优先级,意思也就是优先使用性能较好的分区
注意在配置文件/etc/fstab中的书写:(数字越大,优先级越高,也可以使用swapon -p 来指定)
/dev/hda1 swap swap defaults,pri=10 0 0
/dev/hda5 swap swap defaults,pri=5 0 0
6.一个重要的参数:
sysctl -a | grep vm.swa
linux内核调优过程有几个特殊的值,包括这个,不是具体的百分比,而是一个期望值,在这里越接近0尽量使用cache,越接近100尽量使用swap,只是个趋向值。现在默认是60,DBA通常是90以上
7.两个一般不调节的值:
vm.swap_token_timeout = 300 时间间隔
vm.page-cluster = 3 一次性写入swap的页面数2^3*4K = 32K
下面说说内存的优化:
linux下内存分配的管理主要通过内核参数来控制:
1.与容量相关的内存可调参数
以下参数位于 proc 文件系统的 /proc/sys/vm/ 目录中。
overcommit_memory :规定决定是否接受超大内存请求的条件。这个参数有三个可能的值:
* 0 默认设置。内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。不让过度使用,直接报错
* 1 内核执行无内存过量使用处理。使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能。应用程序在需要时分配,允许过度使用
* 2 内存拒绝等于或者大于总可用 swap 大小以及 overcommit_ratio 指定的物理 RAM 比例的内存请求。如果您希望减小内存过度使用的风险,这个设置就是最好的。 将swap直接使用,使用的内存 = swap + ram * 50%
注意:只为 swap 区域大于其物理内存的系统推荐这个设置overcommit_ratio,将 overcommit_memory 设定为 2 时,指定所考虑的物理 RAM 比例。默认为 50。
2.Out-of-Memory Kill 可调参数
内存不足(OOM)指的是所有可用内存,包括 swap 空间都已被分配的计算状态。默认情况下,这个状态可造成系统 panic,并停止如预期般工作。但将 /proc/sys/vm/panic_on_oom 参数设定为 0 会让内核在出现 OOM 时调用 oom_killer 功能。通常 oom_killer 可杀死偷盗进程,并让系统正常工作。
可在每个进程中设定以下参数,提高您对被 oom_killer 功能杀死的进程的控制。它位于 proc 文件系统中 /proc/pid/ 目录下,其中 pid 是进程 ID。oom_adj定义 -16 到 15 之间的一个数值以便帮助决定某个进程的 oom_score。oom_score 值越高,被 oom_killer 杀死的进程数就越多。将 oom_adj 值设定为 -17 则为该进程禁用 oom_killer。
注意:由任意调整的进程衍生的任意进程将继承该进程的 oom_score。例如:如果 sshd 进程不受 oom_killer 功能影响,所有由 SSH 会话产生的进程都将不受其影响。这可在出现 OOM 时影响 oom_killer 功能救援系统的能力。
!!!!!下篇文章会介绍CPU的监控项--上51CTO评论我的文章。及时改进
本文出自 “asinego” 博客,谢绝转载!
原文地址:http://asinego.blog.51cto.com/11460064/1905622