JAVA编程-高性能IO操作方式

IO高性能优化框架

  • 提前读,预读 (减少读数据的时间)

  • 延迟写(减少磁盘的次数)

  • 优化物理块的分布,分片(减少磁臂移动距离)

  • 临时文件(文件缓存,顺序读写减少磁臂移动距离)

  • 内存映射(逻辑上属于磁盘, 物理上在内存中)

高性能IO操作方式

  • FileChannel使用的ByteBuffer一定要以4k的倍数操作

  • 写入一定要加锁,不然并发时数据一定会错乱

  • 保持顺序读或写操作(如果不能保持,请将文件分片后再保持顺序读写)

  • 写入读取请使用堆外内存

  • 复制内存请使用: 堆内System.arraycopy, 堆外unsafe.copyMemory

  • 可以尝试使用DIO. https://github.com/smacke/jaydio

java.nio底层使用的类如下

核心包

  • sun.nio.ch (IO通道)

  • sun.nio.fs (文件系统)

类关系如下

  • 父类 sun.nio.ch.NativeDispatcher

  • 子类-文件 -> sun.nio.ch.FileDispatcherImpl

  • 子类-TCP -> sun.nio.ch.SocketDispatcher

  • 子类-UDP -> sun.nio.ch.DatagramDispatcher

IO拷贝的逻辑

  • NativeDispatcher接口

          read write close(FileDescriptor, long address, int length)
            
          读 写 关(文件句柄, 堆外内存地址, 读/写长度)
    
  • debug后可以看出,所有IO操作都是通过 sun.nio.ch.IOUtil操作的. IOUtil进行如下判断

       如果是堆内内存,那么会将堆内内存转成堆外内存操作 
           转换会调用sun.nio.ch.Util.getTemporaryDirectBuffer(),
           这个里面有ThreadLocal<Util.BufferCache> bufferCache
        
       如果是堆外内存,不转换直接调用本地方法
    
  • 总结 (所有IO操作都是用堆外内存操作的)

    如果是堆内内存,会发生一次拷贝至堆外内存. 
    拷贝方式 -> System.arraycopy(堆外到堆内) 或 unsafe.copyMemory(堆内到堆外) 
    

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

备案信息公示
京ICP备18003381号
京ICP备18003381号-1