前言
文章开始前先推荐两本书,《深入理解linux内核》可以帮助大家对内核有一个系统的理解,《深入理解计算机系统》可以夯实对操作系统的了解
1. 物理内存:
物理内存中有内核,有应用程序,程序在物理内存中是不连续的。但是在线性地址中是连续的。线性地址和物理地址有一个映射关系。计算机操作系统在分配数据和程序的时候不会全量分配,程序在执行一段之后会存在缺页异常,这个时候会存在用户态和内核态的切换,内核会从磁盘加载需要的数据。
2. 内核配置参数:
vm.dirty_background_ratio 内存空间大小比例达到多少后才持久化到磁盘,
vm.dirty_ratio 前台写,达到一定比例后,用户程序会阻塞,等到持久化完成后才能继续运行
vm.dirty_background_bytes = 1048576
vm.dirty_ratio = 0 前台程序进行持久化。
vm.dirty_bytes = 1048576
vm.dirty_writeback_centisecs = 5000
vm.dirty_expire_centisecs = 30000 dirty页超过多久后会被持久化
当内存空间不足时,脏页不会被LRU算法淘汰掉。内核会判断pageCache是不是dirty,如果是就持久化到磁盘中,如果不是dirty,状态时cache,就会被直接淘汰掉。
3. Buffer为什么比直接内存IO快?
如果使用buffer,JVM会在自己的堆内存中开辟一块缓冲区,当需要进行持久化的时候,调用系统函数system_call,把缓冲区的数据write到内核的pageCache中。这个过程存在用户态和内核态的切换,比较耗时。如果不用缓冲区Buffer,则每次都要调用systemcall函数,会存在用户态内核态的频繁切换。java程序不推荐使用直接io,推荐使用buffer,直接io会导致单位时间内,用户态和内核态的切换次数增加。追踪底层程序,可以看到调用write的次数在使用buffer的情况下变少。