關(guān)于I/O內(nèi)存映射。
設(shè)備通過(guò)控制總線,數(shù)據(jù)總線,狀態(tài)總線與CPU相連??刂瓶倲?shù)傳送控制信號(hào)。在傳統(tǒng)的操作中,都是通過(guò)讀寫(xiě)設(shè)備寄存器的值來(lái)實(shí)現(xiàn)。但是這樣耗費(fèi)了CPU時(shí)鐘。而且每取一次值都要讀取設(shè)備寄存器,造成了效率的低下。在現(xiàn)代操作系統(tǒng)中。引用了I/O內(nèi)存映射。即把寄存器的值映身到主存。對(duì)設(shè)備寄存器的操作,轉(zhuǎn)換為對(duì)主存的操作,這樣極大的提高了效率。
傳統(tǒng)的處理方法為:當(dāng)設(shè)備接收到數(shù)據(jù),向CPU報(bào)告中斷。CPU處理中斷,CPU把數(shù)據(jù)從設(shè)備的寄存器數(shù)據(jù)讀到內(nèi)存。
在現(xiàn)代操作系統(tǒng)中引入的DMA設(shè)備,設(shè)備接收到數(shù)據(jù)時(shí),把數(shù)據(jù)放至DMA內(nèi)存,再向CPU產(chǎn)生中斷。這樣節(jié)省了大量的CPU時(shí)間
什么是零拷貝?
零拷貝描述的是CPU不執(zhí)行拷貝數(shù)據(jù)從一個(gè)存儲(chǔ)區(qū)域到另一個(gè)存儲(chǔ)區(qū)域的任務(wù),這通常用于通過(guò)網(wǎng)絡(luò)傳輸一個(gè)文件時(shí)以減少CPU周期和內(nèi)存帶寬。
避免數(shù)據(jù)拷貝
零拷貝給我們帶來(lái)的好處
零拷貝完全依賴于操作系統(tǒng)。操作系統(tǒng)支持
把文件數(shù)據(jù)通過(guò)網(wǎng)絡(luò)發(fā)送出去,減少了上下文的切換,內(nèi)核的緩存數(shù)據(jù)到直接網(wǎng)卡數(shù)據(jù)也不用CPU去復(fù)制,由DMA完成
通過(guò)sendfile實(shí)現(xiàn)的零拷貝I/O只使用了2次用戶空間與內(nèi)核空間的上下文切換,以及3次數(shù)據(jù)的拷貝。實(shí)現(xiàn)了把數(shù)據(jù)從文件發(fā)送到網(wǎng)卡。
read(file, tmp_buf, len);write(socket, tmp_buf, len);
第4步DMP把socket緩存數(shù)據(jù)復(fù)制到網(wǎng)卡緩存上
經(jīng)過(guò)4次上下文切換,4次數(shù)據(jù)拷貝,在數(shù)據(jù)量比較大時(shí),性能比sendfile方式低下
mmap(內(nèi)存映射)是一個(gè)比sendfile昂貴但優(yōu)于傳統(tǒng)I/O的方法。
MappedByteBuffer
在調(diào)用FileChannel.map()時(shí)使用。 與DirectByteBuffer類似,這也是JVM堆外部的情況。 它基本上作為OS mmap()系統(tǒng)調(diào)用的包裝函數(shù),以便代碼直接操作映射的物理內(nèi)存數(shù)據(jù)。
HeapByteBuffer
在調(diào)用ByteBuffer.allocate()時(shí)使用。 它被稱為堆,因?yàn)樗4嬖贘VM的堆空間中,因此你可以獲得所有優(yōu)勢(shì),如GC支持和緩存優(yōu)化。 但是,它不是頁(yè)面對(duì)齊的,這意味著如果你需要通過(guò)JNI與本地代碼交互時(shí),比如寫(xiě)入網(wǎng)卡,寫(xiě)入磁盤(pán),JVM將不得不復(fù)制到系統(tǒng)的頁(yè)緩沖區(qū)空間。
DirectByteBuffer
在調(diào)用ByteBuffer.allocateDirect()時(shí)使用。 JVM在堆空間之外分配內(nèi)存空間。 因?yàn)樗皇怯蒍VM管理的,所以你的內(nèi)存空間是頁(yè)面對(duì)齊的,不受GC影響,這使得它成為處理本地代碼的完美選擇。 然而,你要C程序員一樣,自己管理這個(gè)內(nèi)存,必須自己分配和釋放內(nèi)存來(lái)防止內(nèi)存泄漏。
splice
在兩個(gè)文件描述符之間傳輸數(shù)據(jù),不用拷貝。但輸入和輸出文件描述符必須有一個(gè)是pipe。也就是說(shuō)如果你需要從一個(gè)socket 傳輸數(shù)據(jù)到另外一個(gè)socket,是需要使用 pipe來(lái)做為中介的
splice (socket1_fd, pipe_fd) splice (pipl_fd, socket2_fd)
聯(lián)系客服