zoukankan      html  css  js  c++  java
  • 优化-内存

    内存子系统
    同步 异步
    client -- squid/varnish -- web
    web程序 -- memcache/redis -- mysql
    CPU(进程)---内存(swap)---磁盘  (异步)
    内存优点:速度非常快的存储介质
      缺点:相对磁盘,价格贵,存储空间小,存放数据不是永久存放
    内存” 包括物理内存和虚拟内存(swap)
    虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,
    物理内存(RAM)和硬盘的一部分空间(SWAP)组合在一起作为虚拟内存为计算机提供了一个连贯的虚拟内存空间,
    好处是我们拥有的内存 ”变多了“,可以运行更多、更大的程序,
    坏处是把部分硬盘当内存用整体性能受到影响,硬盘读写速度要比内存慢几个数量级,
    并且 RAM 和 SWAP 之间的交换增加了系统的负担。
    虚拟内存
    把内存上暂时用不到的数据,但不能不用的数据,临时保存到磁盘(swap)或者磁盘文件(虚拟内存文件)中。或者物理内存不够用了,会使用到swap虚拟内存.
    但需要用到这些数据的时候,就重新从磁盘上读取到内存中。
    由内核kswapd进程完成
    ps -ef |grep kswapd
    # free
    total used free shared buffers cached
    Mem: 3801928 3656892 145036 0 88336 2898552
    -/+ buffers/cache: 670004 3131924
    Swap: 4194296 796 4194296
    linux的内存使用和windows不一样,windows使用过的内存,当程序关闭会释放。linux使用过的内存,程序关闭也不释放,而是缓存(buffer+cached)
    所以上面看到used3656892几乎用完,这是一个误区.你应该看第二行的670004才是使用的内存.
    # echo $[670004+88336+2898552]
    3656892
    # echo $[3131924-88336-2898552]
    145036
    注意生产环境不要使用下面的命令
    echo 3 > /proc/sys/vm/drop_caches --此命令是扔掉内存中的缓存
    内存页(page) 默认是4K大小。这是操作内存数据的最小基本单位(类似于文件系统里的block)
    内存分页(paging) 内核经常扫描内存,如果发现内存的空闲空间低于某个值,那么就会把内存上的数据同步到硬盘。
    这些一般都是曾经打开过的文件,这些文件数据加载到内存中,然后已经被修改过,
    # /usr/bin/time -v mysql --此命令显示的倒数第二行有内存页的大小
    ......
    Page size (bytes): 4096
    Exit status: 1
    # /usr/bin/time -v date
    ...
    Major (requiring I/O) page faults: 0 主要页面故障
    Minor (reclaiming a frame) page faults: 204 次要页面故障
    ...
    Page size (bytes): 4096 《--内存页为4K
    主要页面故障:(类似于缓存未命中miss)
    当执行某个进程的时候,进程需要读取某些数据,而这些数据在cache,buffer(在内存中)找不到,就会产生一次主要页面故障。
    次要页面故障: (类似于缓存命中hit)
    进程在执行的时候,需要的数据在内存中可以找到,就叫做次要页面故障。
    系统为了提高访问效率,总是把数据缓存起来,以便在内存中直接操作数据,减少磁盘的读写。
    其实就是一个尽可能减少主要页面故障,增加次要页面故障的过程
    小实例测试:
    /usr/bin/time -v firefox 运行两次可以看到,第二次运行已经主要页面故障为0了,因为进程所需的数据已经在内存中,并且感觉到firefox打开速度变快
    echo 3 > /proc/sys/vm/drop_caches --此命令是扔掉内存中的缓存
    然后再用/usr/bin/time -v firefox 执行,会发现主要页面故障又不为0了,而且明显感觉到firefox打开速度变慢.说明缓存没有命中
    CPU(进程)---内存(swap)---磁盘  (异步)
    总结:
    1,cpu速度快,磁盘速度慢,CPU运算需要从磁盘取数据,那么在中间加内存可以提高性能,做缓存
    2,内存包括物理内存和虚拟内存(swap)
    3,cpu要取数据,先找内存,内存能找到(内存hit),则直接把数据给cpu,这样效率高;cpu如果在内存没有找到(内存miss),则找磁盘,这样效率低;
    4,从磁盘取的数据会先放到内存缓存起来,以便cpu下次来就可以直接hit命中;如果内存的空间不够了,那么从磁盘取的新的数据会挤掉最近最少使用LRU(least recently used)的数据
    5,内核会在物理内存不够时,使用虚拟内存或者是物理内存有空闲时,也会使用虚拟内存(会使用最近最少使用算法 LRU,把最近不常用的也会给虚拟内存);也就是说物理内存够或者不够都可能会使用swap(不需要人为控制,由内核来控制)
    6,物理内存与虚拟内存交换的单位就是内存页,内存页大小为4096字节
    7,linux系统会把你访问过的程序或文件都缓存起来,甚至你的程序关闭也不释放相关的缓存.
    8,内存里被CPU处理过的数据(或者叫脏数据dirty data,这些数据最终要放回磁盘)会在满足特定条件时才会由pdflush进程写到磁盘(这些条件可以通过修改内核参数来实现优化)
    查看内存状态相关的命令
    free,top,vmstat,sar
    # vmstat
    procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
    r b swpd free buff cache si so bi bo in cs us sy id wa st
    0 0 0 2258668 7692 1052824 0 0 134 21 298 423 4 1 95 1 0
    --从上面的比较可以看到,vmstat里的free,buff,cache的值对应free 命令里的free,buffers,cached
    si 有多少数据从swap到物理内存
    so 有多少数据从物理内存到swap
    bi 有多少数据从块设备读取到内存中
    bo 有多少数据从内存中写到块设备中
    CPU---内存(swap)---磁盘  (异步)
    # sar -B 2 3
    Linux 2.6.32-279.el6.x86_64 (li.cluster.com) 04/25/2014 _x86_64_ (2 CPU)
    11:28:53 AM pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff
    11:28:55 AM 0.00 0.00 45.23 0.00 368.34 0.00 0.00 0.00 0.00
    11:28:57 AM 0.00 19.90 78.11 0.00 533.33 0.00 0.00 0.00 0.00
    11:28:59 AM 0.00 0.00 46.50 0.00 177.50 0.00 0.00 0.00 0.00
    Average: 0.00 6.67 56.67 0.00 360.00 0.00 0.00 0.00 0.00
    pgpgin/s 每秒从磁盘page in内存的 kilobytes
    pgpgout/s 每秒从内存page out磁盘的 kilobytes
    fault/s 每秒的(major+minor) page faults之和
    majflt/s 每秒的major page faults数
    --如果pgpgin和pgpgout很多,majflt/fault这个内存miss率很高.而且系统运行的程序也是固定的,这就有可能说明内存不够用了.造成缓存不了所有数据,以致内存命中率低
    到底怎么样才说明内存不够?
    结合free,vmstat,sar命令综合分析
    如果你使用vmstat看到swapd使用比较多,free+buff+cache的值很小,并且si和so比较频繁,说明可用内存很小,并且swap使用很多,swap交互也频繁,表明内存遇到瓶颈了
    如果你使用sar -B来看,看到pgpgin/s和pgpgout/s很频繁说明内存和磁盘交互很频繁。majflt/s除以fault/s得到内存MISS率变高,而且pgfree/s可用内存列表变小。也能说明内存不够了。
    ============================================================
    内核参数的基本操作:
    sysctl -a --查看当前所有内核参数及其对应的值
    内核参数配置文件
    /etc/sysctl.conf
    修改保存后,sysctl -p让其生效
    例如:
    # sysctl -a |grep ip_forward
    net.ipv4.ip_forward = 1
    这个参数对应的/proc路径为/proc/sys/net/ipv4/ip_forward
    # sysctl -a |grep file-max
    fs.file-max = 381908
    这个参数对应的/proc路径为/proc/sys/fs/file-max
    2,如何修改内核参数
    临时修改,重启后不生效;如
    # echo 1 > /proc/sys/net/ipv4/ip_forward
    # sysctl -w net.ipv4.ip_forward=1
    永久生效,需要修改/etc/sysctl.conf配置文件
    net.ipv4.ip_forward = 1 --修改,没有此参数就手动加上
    保存后,记得要用sysctl -p使之生效
    ============================================================
    与内存和swap有关的内核参数调整
    # cat /proc/sys/vm/swappiness
    60
    swappiness表示使用swap分区的使用程度,可以适当调整swappiness=0的时候表示尽可能使用物理内存空间.swappiness=100积极使用swap.
    --基本调优规则为:如果物理内存够大,那么就尽量不要使用swap,可以把此参数调小如swappiness=10.
    # sysctl -a |grep min_free
    vm.min_free_kbytes = 67584
    内存最小的free预留值。调太大,会造成可用内存减小。调太小,可能会造成系统急用内存时没有足够的预留。
    # cat /proc/sys/vm/dirty_background_ratio
    10
    --这里表示内存里的脏数据(dirty data)到达10%,会触发写到磁盘
    # cat /proc/sys/vm/dirty_ratio
    20
    --这里表示内存里的脏数据到达20%时,就不能再写入脏数据了,也就表示要让应用程序等待了,等这个值下降,才能继续写
    程序经cpu处理的数据--》内存 --》 磁盘
    --这两个参数合起来理解就是:内存脏数据到dirty_background_ratio定义的10%时,就会触发数据写到磁盘(但是这个过程是异步的,也就是说还是会有别的应用程序的脏数据能继续写到内存),如果应用程序往内存里写的比内存往磁盘里写得快,还是有可能达到dirty_ratio定义的20%时,那么就要让写脏数据的应用程序等待,直到它降低到20%以下,再继续写
    理解了上面两个参数的意思,现在如何来调整
    1,dirty_background_ratio (内存写到磁盘)
    把它调大,会提高写入磁盘速度(因为一次写的数据量大);但这样也有缺点,有可能一次写的数据量过大,造成磁盘IO峰值。还有就是如果物理内存不够,调大,会压缩物理内存缓存的空间,会进一步造成内存命中率下降.
    把它调小,虽然速度会较慢,但可以削平IO峰值
    2,dirty_ratio (cpu写到内存)
    在应用程序写内存繁忙时,可以把dirty_ratio调大,可以缓解应用程序的等待。如果物理内存不够,调大,会压缩物理内存缓存的空间,会进一步造成内存命中率下降.
  • 相关阅读:
    (打包报错)AS打包报错:Generate Signed APK: Errors while building APK. You can find the errors in the 'Messages' view.
    NABCD
    石家庄地铁站项目最终总结报告
    团队冲刺2.7
    团队冲刺2.6
    团队冲刺2.5
    团队冲刺2.4
    团队冲刺2.3
    用户体验评价——win10自带微软拼音输入法
    团队冲刺2.2
  • 原文地址:https://www.cnblogs.com/skyzy/p/9201440.html
Copyright © 2011-2022 走看看