jvm管理的内存有heap、stack、其它寄存器。
Heap用来存放实例化之后的java对象(包括class及文件流)
On-heap是指在堆内存,由GC进行创建回收,通过-Xmx设置大小。
Off-heap是指在堆外内存,不由GC创建,但可以通过full GC回收,通过-XX:MaxDirectMemorySize设置大小。
JDK的ByteBuffer的创建时支持nonDirect及Direct
nonDirect的对象数据在堆内创建
缓存数据存放一般支持On-heap
及Off-heap:
堆内存放开销小、效率高、存储大小受限制,
堆外存放开销大(还是比disk快,建议使用缓冲池)、存储容量较大,适合存储不怎么变化的数据。
网络编程的zero-copy原理:数据不需要再native memory和jvm memory中来回copy
传统数据复制方式:
- read() 调用导致一次从user mode到kernel
mode的上下文切换。在内部调用了sys_read() 来从文件中读取data。第一次copy由DMA (direct
memory access)完成,将文件内容从disk读出,存储在kernel的buffer中。
- 然后请求的数据被copy到user buffer中,此时read()成功返回。调用的返回触发了第二次context switch:
从kernel到user。至此,数据存储在user的buffer中。
- send()
Socket call 带来了第三次context switch,这次是从user mode到kernel
mode。同时,也发生了第三次copy:把data放到了kernel adress space中。当然,这次的kernel
buffer和第一步的buffer是不同的buffer。
- 最终 send() system call 返回了,同时也造成了第四次context switch。同时第四次copy发生,DMA egine将data从kernel
buffer拷贝到protocol engine中。第四次copy是独立而且异步的
Zero-copy的复制方式
- transferTo()方法使得文件内容被copy到了kernel buffer,这一动作由DMA engine完成。
- 没有data被copy到socket buffer。取而代之的是socket
buffer被追加了一些descriptor的信息,包括data的位置和长度。然后DMA engine直接把data从kernel
buffer传输到protocol engine,这样就消除了唯一的一次需要占用CPU的拷贝操作。
Java
NIO中的FileChannel.transferTo()实现了零拷贝。
|