- 基本概念
- 什么是零拷贝?
- 在操作数据时,不需要将数据从一个内存区域copy到另一个内存区域,从而减少一次数据拷贝,提升CPU效率;
- OS的Zero-Copy和Netty的Zero-Copy有什么区别?
- OS的Zero-Copy:通常是指避免在用户态和内核态之间的数据拷贝;
- Netty的Zero-Copy:完全是在用户态(Java层面)的,偏向于优化数据;
- 什么是DMA?
- Direct Memory Access直接内存读取
- 什么是零拷贝?
- 传统拷贝技术
- NIO中的零拷贝实践 https://toutiao.io/posts/erylvi/preview
- Netty中的零拷贝实践 https://blog.csdn.net/baiye_xing/article/details/73351252
- 必看:蚂蚁二面,面试官问我零拷贝的实现原理,当场懵了
https://www.shangyexinzhi.com/article/1696425.html
20200504 update
- 数据从磁盘传输到网络的过程:
图中有四次拷贝,其中最占资源和时间的是#2、#3,因为是CPU Copy
- 优化
- Linux2.1 数据从buffer直接拷贝到socket。Java NIO的transferTo()可以实现
- 但是#2还是用到了CPU Copy
- 优化
- Linux2.4 DMA可以直接把数据从Read Buffer拷贝到协议引擎,消除了最后一次CPU Copy
- 注意:零拷贝是指数据没有经过CPU Copy,在用户态下经历了0次拷贝;
- 哪些地方用到零拷贝技术
4.1 java nio
- java nio中的channel 相当于内核的read buffer,buffer相当于OS用户层的buffer;
- 堆外内存DirectBuffer需要应用程序手动回收,堆内存HeapBuffer会在GC的时候被回收;
- 零拷贝主要实现类:
- MappedByteBuffer:基于mmap实现
- DirectByteBuffer:
- FileChannel:transferFrom和transferTo通过Channel间数据传输实现;
4.2 netty
- Netty的零拷贝和上面OS层面的零拷贝还不一样,Netty的零拷贝还是基于用户态的;
- 零拷贝仅作用在用户态,那Netty是如何实现的呢?
- 接口ChannelBuffer
- 主要实现:CompositeChannelBuffer— 将多个ChannelBuffer的引用组合起来,避免拷贝;
4.3 kafka
- 索引文件通过mmap+write
- 数据文件通过sendfile