• Linux内存详解


    --Linux内存详解

    -----------------2014/05/24

    Linux的内存上表现的不像windows那么直观,本文准备详细的介绍一下Linux的内存。

    请看这下有linux命令free和vmstat输出的内存信息。

    Mem行used表示已经分配的内存,free表示尚未分配的内存,shared表示共享内存。

    计算方法:缓存统计行free=Mem(free)+Mem(buffers)+Mem(cached)

    共享内存

    对于共享内存(Shared memory),主要用于在UNIX 环境下不同进程之间共享数据,是进程间通信的一种方法,一般的应用程序不会申请使用共享内存,笔者也没有去验证共享内存对上面等式的影响。

    例如Linux平台的oracle为多进程程序,SGA和PGA都是各进程共享和通信的数据区域,所有可以看到分配了很大的共享内存。而MySQL为多线程,系统级表现为一个进程,不需要共享内存。

    Linux的cache和buffer有何区别

    Linux下对文件的访问和设备的访问通常会被cache起来加快访问速度,这个是系统的默认行为。 而cache需要耗费我们的内存,虽然这个内存最后可以通过echo 3>/proc/sys/vm/drop_caches这样的命令来主动释放。但是有时候我们还是需要理解谁消耗了我们的内存。

    我们来先了解下内存的使用情况:


     

    [root@my031045 ~]# free
                 total       used       free     shared    buffers     cached
    Mem:      24676836     626568   24050268          0      30884     508312
    -/+ buffers/cache:      87372   24589464
    Swap:      8385760

    Page cache和buffer cache一直以来是两个比较容易混淆的概念,在网上也有很多人在争辩和猜想这两个cache到底有什么区别,讨论到最后也一直没有一个统一和正
    确的结论,在我工作的这一段时间,page cache和buffer cache的概念曾经困扰过我,但是仔细分析一下,这两个概念实际上非常的清晰。如果能够了解到这两个cache的本质,那么我们在分析io问题的时候可能会更加得心应手。 Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当page cache的数据需要刷新时,page cache中的数据交给buffer cache,但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作。

    Buffer cache是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。

    简单说来,page cache用来缓存文件数据,buffer cache用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到page cache,如果直接采用
    dd等工具对磁盘进行读写,那么数据会缓存到buffer cache补充一点,在文件系统层每个设备都会分配一个def_blk_ops的文件操作方法,这是设备的操作方法,在每个设备的inode下面会存在一个radix tree,这个radix tree下面将会放置缓存数据的page页。这个page的数量将会在top程序的buffer一栏中显示。如果设备做了文件系统,那么会生成一个inode,这个inode会分配ext3_ops之类的操作方法,这些方法是文件系统的方法,在这个inode下面同样存在一个radix tree,这里会缓存文件的page页,缓存页的数量在top程序的cache一栏进行统计。从上面的分析可以看出,2.6内核中的buffer cache和page cache在处理上是保持一致的,但是存在概念上的差别,page cache针对文件的cache,buffer是针对磁盘块数据的cache,仅此而已。

    有了伟大的systemtap, 我们可以用stap脚本来了解谁在消耗我们的cache了:

    #这个命令行用来调查谁在加数据入page_cache

    [root@my031045 ~]# stap -e 'probe vfs.add_to_page_cache {printf("dev=%d, devname=%s, ino=%d, index=%d, nrpages=%d/n", dev, devname, ino, index, nrpages )}'
    ...
    dev=2, devname=N/A, ino=0, index=2975, nrpages=1777
    dev=2, devname=N/A, ino=0, index=3399, nrpages=2594
    dev=2, devname=N/A, ino=0, index=3034, nrpages=1778
    dev=2, devname=N/A, ino=0, index=3618, nrpages=2595
    dev=2, devname=N/A, ino=0, index=1694, nrpages=106
    dev=2, devname=N/A, ino=0, index=1703, nrpages=107
    dev=2, devname=N/A, ino=0, index=1810, nrpages=210
    dev=2, devname=N/A, ino=0, index=1812, nrpages=211
    ...
    

       这时候我们拷贝个大文件:

    [chuba@my031045 ~]$ cp huge_foo.file  bar
    
    #这时候我们可以看到文件的内容被猛的添加到cache去:
    ...
    dev=8388614, devname=sda6, ino=2399271, index=39393, nrpages=39393
    dev=8388614, devname=sda6, ino=2399271, index=39394, nrpages=39394
    dev=8388614, devname=sda6, ino=2399271, index=39395, nrpages=39395
    dev=8388614, devname=sda6, ino=2399271, index=39396, nrpages=39396
    dev=8388614, devname=sda6, ino=2399271, index=39397, nrpages=39397
    dev=8388614, devname=sda6, ino=2399271, index=39398, nrpages=39398
    dev=8388614, devname=sda6, ino=2399271, index=39399, nrpages=39399
    dev=8388614, devname=sda6, ino=2399271, index=39400, nrpages=39400
    dev=8388614, devname=sda6, ino=2399271, index=39401, nrpages=39401
    dev=8388614, devname=sda6, ino=2399271, index=39402, nrpages=39402
    dev=8388614, devname=sda6, ino=2399271, index=39403, nrpages=39403
    dev=8388614, devname=sda6, ino=2399271, index=39404, nrpages=39404
    dev=8388614, devname=sda6, ino=2399271, index=39405, nrpages=39405
    dev=8388614, devname=sda6, ino=2399271, index=39406, nrpages=39406
    dev=8388614, devname=sda6, ino=2399271, index=39407, nrpages=39407
    dev=8388614, devname=sda6, ino=2399271, index=39408, nrpages=39408
    dev=8388614, devname=sda6, ino=2399271, index=39409, nrpages=39409
    dev=8388614, devname=sda6, ino=2399271, index=39410, nrpages=39410
    dev=8388614, devname=sda6, ino=2399271, index=39411, nrpages=39411
    ...

     

    如果需要手动释放Linux系统的Cache,可以参考博文:http://www.cnblogs.com/jackhub/p/3736877.html

  • 相关阅读:
    类的静态成员
    透彻分析C/C++中memset函数
    排序中的qsort和sort
    NOIP2020 T4微信步数
    NOIP2020 T3移球游戏
    GMOJ 6898. 【2020.11.27提高组模拟】第二题
    虚树学习笔记
    GMOJ 6860. 【2020.11.14提高组模拟】鬼渊传说(village)
    CSP-S 2020 T3函数调用
    CSP-S 2020 T4贪吃蛇
  • 原文地址:https://www.cnblogs.com/jackhub/p/3749893.html
Copyright © 2020-2023  润新知