根據官方文檔的描述:java
A byte buffer is either direct or non-direct. Given a direct byte buffer, the Java virtual machine will make a best effort to perform native I/O operations directly upon it. That is, it will attempt to avoid copying the buffer's content to (or from) an intermediate buffer before (or after) each invocation of one of the underlying operating system's native I/O operations.
byte byffer
能夠是兩種類型,一種是基於直接內存(也就是非堆內存);另外一種是非直接內存(也就是堆內存)。api
對於直接內存來講,JVM將會在IO操做上具備更高的性能,由於它直接做用於本地系統的IO操做。而非直接內存,也就是堆內存中的數據,若是要做IO操做,會先複製到直接內存,再利用本地IO處理。緩存
從數據流的角度,非直接內存是下面這樣的做用鏈:網絡
本地IO-->直接內存-->非直接內存-->直接內存-->本地IO
而直接內存是:併發
本地IO-->直接內存-->本地IO
很明顯,再作IO處理時,好比網絡發送大量數據時,直接內存會具備更高的效率。oracle
A direct byte buffer may be created by invoking the allocateDirect factory method of this class. The buffers returned by this method typically have somewhat higher allocation and deallocation costs than non-direct buffers. The contents of direct buffers may reside outside of the normal garbage-collected heap, and so their impact upon the memory footprint of an application might not be obvious. It is therefore recommended that direct buffers be allocated primarily for large, long-lived buffers that are subject to the underlying system's native I/O operations. In general it is best to allocate direct buffers only when they yield a measureable gain in program performance.
可是,不要高興的太早。文檔中也說了,直接內存使用allocateDirect建立,可是它比申請普通的堆內存須要耗費更高的性能。不過,這部分的數據是在JVM以外的,所以它不會佔用應用的內存。app
因此呢,當你有很大的數據要緩存,而且它的生命週期又很長,那麼就比較適合使用直接內存。只是通常來講,若是不是能帶來很明顯的性能提高,仍是推薦直接使用堆內存。ide
關於直接內存須要注意的,就是上面兩點了,其餘的關於視圖啊、做用鏈啊,都是使用上的問題了。若是有興趣,能夠參考官方API ( 進去後搜索ByteBuffer,就能看到!),裏面有少許的描述!重要的一些用法,還得本身摸索。性能
經過上面的官方文檔,與一些資料的搜索。能夠總結下,直接內存的使用場景:測試
下面用一段簡單的代碼,測試下申請內存空間的速度:
int time = 10000000; Date begin = new Date(); for(int i=0;i<time;i++){ ByteBuffer buffer = ByteBuffer.allocate(2); } Date end = new Date(); System.out.println(end.getTime()-begin.getTime()); begin = new Date(); for(int i=0;i<time;i++){ ByteBuffer buffer = ByteBuffer.allocateDirect(2); } end = new Date(); System.out.println(end.getTime()-begin.getTime());
獲得的測試結果以下:
在數據量提高時,直接內存相比於非直接內存的申請 有十分十分十分明顯的性能問題!
而後在寫段代碼,測試下讀寫的速度:
int time = 1000; Date begin = new Date(); ByteBuffer buffer = ByteBuffer.allocate(2*time); for(int i=0;i<time;i++){ buffer.putChar('a'); } buffer.flip(); for(int i=0;i<time;i++){ buffer.getChar(); } Date end = new Date(); System.out.println(end.getTime()-begin.getTime()); begin = new Date(); ByteBuffer buffer2 = ByteBuffer.allocateDirect(2*time); for(int i=0;i<time;i++){ buffer2.putChar('a'); } buffer2.flip(); for(int i=0;i<time;i++){ buffer2.getChar(); } end = new Date(); System.out.println(end.getTime()-begin.getTime());
測試的結果以下:
能夠看到直接內存在直接的IO操做上,仍是有明顯的差別的!