网络与IO知识扫盲(2)-PageCache

文章目录

为了提升IO的效率,计算机的整体各处都是存在页缓存的概念的。
作为应用进程来说,一般都会存在以4k为单位的缓存页,也就是buffer,可以想象java中的bufferreader等。。
接着,作为系统内核来说,它内部也存在页缓存(pagecache)。
最后,对于硬盘的驱动本身,也存在缓冲区。
因此可以想象,读取一份文件,会从磁盘驱动本身开始,每次读到缓冲区大小的内容才会向上级返回,这样大大提高IO的效率。

在这里插入图片描述
而除了多级缓存之外,我们也不难想到,IO是个很慢的操作,如果一直让CPU去频繁的跟进IO的操作,那系统效率就太低了!
因此在早期的时候,就已经出现了一个协处理DMA,它来从CPU的手中分担IO的操作,由它专门来进行对磁盘内容读取到内核的操作,而只需要最终的时候发起中断信号让CPU将内核缓冲区来自磁盘已经填满的内容一次刷洗给用户空间的程序。

上面说的,是针对读取IO操作,pagecache的一个作用凸现。
在这里插入图片描述
而实际上,一个进程本身也本质就是一个二进制的落在磁盘上的文件,因此也会涉及到读入用户程序的一个过程,此时也依旧是操作系统先将内容读取到pagecache进行缓存。那这样有什么好处呢?当多个进程同时试图访问一处文件的时候,不需要消耗多份的文件内存,去共享这个缓存就好了。
在linux中包装成fd文件描述符,实际它们指向的是同一份pagecache,只不过各自文件描述符的各自偏移量不同,这样才能保证进程之间对文件的读取互不影响。

实验
在这里插入图片描述
写一个mysh小脚本,待会儿使用的时候参数传给0
在这里插入图片描述

rm -rf *out*
strace -ff -o out  javac OSFileIO.java && java OSFileIO $1

pcstat out.txt
查看文件缓存的大小,100%都在内存中,说明关机就会丢失数据
在这里插入图片描述

OSFileIO.java

public class OSFileIO {

    static byte[] data = "123456789\n".getBytes();
    static String path =  "/root/testfileio/out.txt";

    public static void main(String[] args) throws Exception {
        switch ( args[0]) {
            case "0" :
                testBasicFileIO();
                break;
            case "1":
                testBufferedFileIO();
                break;
            case "2" :
                testRandomAccessFileWrite();
            case "3":
//                whatByteBuffer();
            default:
        }
    }


    //最基本的file写
    public static  void testBasicFileIO() throws Exception {
        File file = new File(path);
        FileOutputStream out = new FileOutputStream(file);
        while(true){
//            Thread.sleep(10);
            out.write(data);
        }
    }

    //测试buffer文件IO
    //  jvm  8kB   syscall  write(8KBbyte[])

    public static void testBufferedFileIO() throws Exception {
        File file = new File(path);
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        while(true){
            Thread.sleep(10);
            out.write(data);
        }
    }

用上面的mysh启动,传参为0,也就是执行了testBasicFileIO()这个方法
测试突然断电。断电前我们看到,out.txt文件在不断增大:
在这里插入图片描述

断电后重启,文件大小都是0:
在这里插入图片描述
上面这个测试说明了缓冲区的存在。在一段时间内,并没有进行磁盘的刷写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值