【原创】零拷贝概念详解
概述
零拷贝是我们经常听到的一个术语,要解释清楚这个术语,我个人觉得需要说明三个场景。
- Java中的DirectBuffer;
- Java中的transferTo,底层就是Linux的sendFile;
- Linux中的Direct IO;
本系列分三篇来讲解。
DirectBuffer的特点
Java中的DirectBuffer的具体用法和API,此处不再赘述。我们主要理解DirectBuffer的原理。
- DirectBuffer是分配在JVM堆外的进程地址空间的,因此,相对于在JVM堆中分配的堆内Buffer,也叫做堆外Buffer。这个地方的堆外,从操作系统的角度讲其实就是JVM进程的地址空间,那么自然也就属于用户空间了,堆也属于JVM进程地址空间。为什么我们要强调用户空间呢?其实是后边的篇幅说明DirectBuffer的“零拷贝”意义。
- DirectBuffer其实是JVM本地代码经过malloc系统调用,在当前JVM进程的地址空间申请的一段内存空间。它的引用依然保存在JVM堆中,只是其存储空间在堆外而已。DirectBuffer的引用一般是直接在JVM堆中的老年代创建的,因此,其回收的时机只有在JVM进行Full GC时。基于这个回收特点,我们需要特别注意,不要频繁的分配大量的DirectBuffer,否则很容易导致内存溢出,而且这个时候的溢出,不是堆溢出,而是本地内存溢出。
DirectBuffer的好处
DirectBuffer带来的性能的提升,其根本原因是节省了一次从堆内空间到堆外空间的Buffer拷贝,下图可以说明这个过程。其实省去的就是红线所示的从堆内存到本地内存的拷贝。
##sendFile
待补充……
##DirectIO
待补充……