美文网首页
Linux磁盘缓存实验

Linux磁盘缓存实验

作者: ShootHzj | 来源:发表于2021-03-08 22:18 被阅读0次

    As原文地址

    https://www.linuxatemyram.com/play.html

    希望你现在不再认为Linux吞掉了你的内存。您可以执行以下一些有趣的操作来了解磁盘缓存的工作方式。

    注意:所示示例适用于2009年及之后的不带SSD的硬件。 您可能需要将此处的几个示例数字乘以10才能看到明显的效果。

    磁盘缓存对应用程序内存分配的影响

    既然我已经声明了 磁盘缓存并不影响应用程序获取内存。那我们就从这里开始。这是一个C代码munch.c尽可能地吞噬内存,直到程序异常退出,或者达到指定的限制

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char** argv) {
        int max = -1;
        int mb = 0;
        char* buffer;
    
        if(argc > 1)
            max = atoi(argv[1]);
    
        while((buffer=malloc(1024*1024)) != NULL && mb != max) {
            memset(buffer, 0, 1024*1024);
            mb++;
            printf("Allocated %d MB\n", mb);
        }
    
        return 0;
    }
    

    内存不足并不是一件有趣的事,但是OOM杀手应该结束这个过程,希望其余的一切都不会受到干扰。 我们必须要禁用交换功能,否则应用程序也会吞噬掉交换内存。

    sudo swapoff -a
    free -m
    

    你的free输出可能不一样,拥有一列available,而不是-/+这一行

                 total       used       free     shared    buffers     cached
    Mem:          1504       1490         14          0         24        809
    -/+ buffers/cache:        656        848
    Swap:            0          0          0
    
    $ gcc munch.c -o munch
    
    $ ./munch
    Allocated 1 MB
    Allocated 2 MB
    (...)
    Allocated 877 MB
    Allocated 878 MB
    Allocated 879 MB
    Killed
    
    $ free -m
                 total       used       free     shared    buffers     cached
    Mem:          1504        650        854          0          1         67
    -/+ buffers/cache:        581        923
    Swap:            0          0          0
    

    尽管free显示只有14MB可用,但这也没有阻挡应用程序吞噬了879MB内存。然后,cache已经快空了,但是随着文件的读取,写入,它会逐渐填满。试试看。

    磁盘缓存对交换的影响

    我也说了磁盘缓存并不会导致应用程序使用交换内存。让我们也来试试,还是使用上次的程序。这次我们开着交换内存来使用它,然后限制它只是用数百兆内存

    $ free -m
                 total       used       free     shared    buffers     cached
    Mem:          1504       1490         14          0         10        874
    -/+ buffers/cache:        605        899
    Swap:         2047          6       2041
    
    $ ./munch 400
    Allocated 1 MB
    Allocated 2 MB
    (...)
    Allocated 399 MB
    Allocated 400 MB
    
    $ free -m
                 total       used       free     shared    buffers     cached
    Mem:          1504       1090        414          0          5        485
    -/+ buffers/cache:        598        906
    Swap:         2047          6       2041
    

    它使用了400MB内存,都是从磁盘缓存中获取,没有发起交换。同样地,我们可以再次填充磁盘缓存,并且也不会开始占用交换空间。 如果您在一个终端中运行watch free -m并且在另一个终端运行find -f -exec cat {} +> / dev / null。您可以看到cached增加,而free将减少。 过了一会儿,free 越来越少,但是交换一直没有触发。

    清理磁盘缓存

    为了进行实验,能够删除磁盘缓存非常方便。 为此,我们可以使用特殊文件/proc/sys/vm/drop_caches。 通过向其写入3,我们可以清除大部分磁盘缓存:

    $ free -m
                 total       used       free     shared    buffers     cached
    Mem:          1504       1471         33          0         36        801
    -/+ buffers/cache:        633        871
    Swap:         2047          6       2041
    
    $ echo 3 | sudo tee /proc/sys/vm/drop_caches 
    3
    
    $ free -m
                 total       used       free     shared    buffers     cached
    Mem:          1504        763        741          0          0        134
    -/+ buffers/cache:        629        875
    Swap:         2047          6       2041
    

    注意“ buffers”和“ cached”下降,free mem上升,而free + buffers / cache保持不变。

    磁盘缓存在加载时候的作用

    让我们制作两个测试程序,一个用Python,一个用Java。 Python和Java都具有相当大的运行时,必须加载这些运行时才能运行该应用程序。 这是磁盘缓存发挥其魔力的完美场景

    $ cat hello.py
    print "Hello World! Love, Python"
    
    $ cat Hello.java
    class Hello {
        public static void main(String[] args) throws Exception {
            System.out.println("Hello World! Regards, Java");
        }
    }
    
    $ javac Hello.java
    
    $ python hello.py
    Hello World! Love, Python
    
    $ java Hello
    Hello World! Regards, Java
    

    我们的程序运行起来了。现在我们把磁盘缓存清理,查看需要多长时间运行它们

    $ echo 3 | sudo tee /proc/sys/vm/drop_caches
    3
    
    $ time python hello.py
    Hello World! Love, Python
    
    real    0m1.026s
    user    0m0.020s
    sys     0m0.020s
    
    $ time java Hello
    Hello World! Regards, Java
    
    real    0m2.174s
    user    0m0.100s
    sys     0m0.056s
    
    $
    

    哇。 对于Python是1秒,对于Java是2秒? 只是打个招呼。 但是,现在运行它们所需的所有文件都将位于磁盘高速缓存中,因此可以直接从内存中获取它们。 让我们再试一次:

    $ time python hello.py
    Hello World! Love, Python
    
    real    0m0.022s
    user    0m0.016s
    sys     0m0.008s
    
    $ time java Hello
    Hello World! Regards, Java
    
    real    0m0.139s
    user    0m0.060s
    sys     0m0.028s
    
    $
    

    耶! Python现在仅需22毫秒即可运行,而Java使用139ms。 快了45到15倍! 您所有的应用程序都会自动获得提升!

    磁盘缓存在文件读取时候的作用

    让我们做一个大文件,看看磁盘缓存如何影响我们读取它的速度。 我正在制作200MB的文件,但是如果您的可用RAM较少,则可以对其进行调整。

    $ echo 3 | sudo tee /proc/sys/vm/drop_caches
    3
    
    $ free -m
                 total       used       free     shared    buffers     cached
    Mem:          1504        546        958          0          0         85
    -/+ buffers/cache:        461       1043
    Swap:         2047          6       2041
    
    $ dd if=/dev/zero of=bigfile bs=1M count=200
    200+0 records in
    200+0 records out
    209715200 bytes (210 MB) copied, 6.66191 s, 31.5 MB/s
    
    $ ls -lh bigfile
    -rw-r--r-- 1 vidar vidar 200M 2009-04-25 12:30 bigfile
    
    $ free -m
                 total       used       free     shared    buffers     cached
    Mem:          1504        753        750          0          0        285
    -/+ buffers/cache:        468       1036
    Swap:         2047          6       2041
    

    由于文件刚刚被写入,因此它将进入磁盘缓存。 200MB的文件在“缓存”中引起了200MB的增加。 让我们read它,清除缓存,然后再次read以查看它有多快:

    $ time cat bigfile > /dev/null
    
    real    0m0.139s
    user    0m0.008s
    sys     0m0.128s
    
    $ echo 3 | sudo tee /proc/sys/vm/drop_caches
    3
    
    $ time cat bigfile > /dev/null
    
    real    0m8.688s
    user    0m0.020s
    sys     0m0.336s
    
    $
    

    这次提速了超过50倍

    总结

    Linux磁盘缓存非常简单。他使用备用内存大大提高磁盘访问速度,而不会占用应用程序的内存。在Linux上完全使用的ram存储是有效的硬件使用,而不是警告信号。

    缓存的某些部分无法删除,甚至无法容纳新的应用程序。这包括已被某些应用程序锁定的mmap页面,尚未写入存储器的脏页面以及存储在tmpfs中的数据(包括用于共享内存的/ dev / shm)。 mmap锁定的页面被卡在页面缓存中。大部分情况下,脏页都会被迅速写出。如果可能,tmpfs中的数据将被换出。

    相关文章

      网友评论

          本文标题:Linux磁盘缓存实验

          本文链接:https://www.haomeiwen.com/subject/zpbmqltx.html