Java直接内存与堆内存
NIO的Buffer提供了一個(gè)可以不經(jīng)過JVM內(nèi)存直接訪問系統(tǒng)物理內(nèi)存的類——DirectBuffer。 DirectBuffer類繼承自ByteBuffer,但和普通的ByteBuffer不同,普通的ByteBuffer仍在JVM堆上分配內(nèi)存,其最大內(nèi)存受到最大堆內(nèi)存的限制;而DirectBuffer直接分配在物理內(nèi)存中,并不占用堆空間,其可申請的最大內(nèi)存受操作系統(tǒng)限制。
直接內(nèi)存的讀寫操作比普通Buffer快,但它的創(chuàng)建、銷毀比普通Buffer慢。
因此直接內(nèi)存使用于需要大內(nèi)存空間且頻繁訪問的場合,不適用于頻繁申請釋放內(nèi)存的場合。
?
(Note:DirectBuffer并沒有真正向OS申請分配內(nèi)存,其最終還是通過調(diào)用Unsafe的allocateMemory()來進(jìn)行內(nèi)存分配。不過JVM對Direct Memory可申請的大小也有限制,可用-XX:MaxDirectMemorySize=1M設(shè)置,這部分內(nèi)存不受JVM垃圾回收管理。)
以下是一些測試:
代碼:
1 class DirectMemory {2 3 // 分配堆內(nèi)存4 public static void bufferAccess() {5 long startTime = System.currentTimeMillis();6 ByteBuffer b = ByteBuffer.allocate(500);7 for (int i = 0; i < 1000000; i++) {8 for (int j = 0; j < 99; j++)9 b.putInt(j); 10 b.flip(); 11 for (int j = 0; j < 99; j++) 12 b.getInt(); 13 b.clear(); 14 } 15 long endTime = System.currentTimeMillis(); 16 System.out.println("access_nondirect:" + (endTime - startTime)); 17 } 18 19 // 直接分配內(nèi)存 20 public static void directAccess() { 21 long startTime = System.currentTimeMillis(); 22 ByteBuffer b = ByteBuffer.allocateDirect(500); 23 for (int i = 0; i < 1000000; i++) { 24 for (int j = 0; j < 99; j++) 25 b.putInt(j); 26 b.flip(); 27 for (int j = 0; j < 99; j++) 28 b.getInt(); 29 b.clear(); 30 } 31 long endTime = System.currentTimeMillis(); 32 System.out.println("access_direct:" + (endTime - startTime)); 33 } 34 35 public static void bufferAllocate() { 36 long startTime = System.currentTimeMillis(); 37 for (int i = 0; i < 1000000; i++) { 38 ByteBuffer.allocate(1000); 39 } 40 long endTime = System.currentTimeMillis(); 41 System.out.println("allocate_nondirect:" + (endTime - startTime)); 42 } 43 44 public static void directAllocate() { 45 long startTime = System.currentTimeMillis(); 46 for (int i = 0; i < 1000000; i++) { 47 ByteBuffer.allocateDirect(1000); 48 } 49 long endTime = System.currentTimeMillis(); 50 System.out.println("allocate_direct:" + (endTime - startTime)); 51 } 52 53 public static void main(String args[]) { 54 System.out.println("訪問性能測試:"); 55 bufferAccess(); 56 directAccess(); 57 58 System.out.println(); 59 60 System.out.println("分配性能測試:"); 61 bufferAllocate(); 62 directAllocate(); 63 } 64 }結(jié)果:
訪問性能測試: access_nondirect:157 access_direct:134分配性能測試: allocate_nondirect:231 allocate_direct:613可見與在JVM堆分配內(nèi)存(allocate)相比,直接內(nèi)存分配(allocateDirect)的訪問性能更好,但分配較慢。(一般如此,當(dāng)然數(shù)據(jù)量小的話差別不是那么明顯)
?
from:?https://www.cnblogs.com/z-sm/p/6235157.html
總結(jié)
以上是生活随笔為你收集整理的Java直接内存与堆内存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git Tag作用
- 下一篇: Java直接内存与非直接内存性能测试