NIO的Buffer提供了一个可以不经过JVM内存直接访问系统物理内存的类——DirectBuffer。 DirectBuffer类继承自ByteBuffer,但和普通的ByteBuffer不同,普通的ByteBuffer仍在JVM堆上分配内存,其最大内存受到最大堆内存的限制;而DirectBuffer直接分配在物理内存中,并不占用堆空间,其可申请的最大内存受操作系统限制。
直接内存的读写操作比普通Buffer快,但它的创建、销毁比普通Buffer慢。
因此直接内存使用于需要大内存空间且频繁访问的场合,不适用于频繁申请释放内存的场合。
以下是一些测试:
代码:
1 public class DirectMemory { 2 // 直接分配内存 3 public static void directAccess() { 4 long startTime = System.currentTimeMillis(); 5 ByteBuffer b = ByteBuffer.allocateDirect(500); 6 for (int i = 0; i < 1000000; i++) { 7 for (int j = 0; j < 99; j++) 8 b.putInt(j); 9 b.flip(); 10 for (int j = 0; j < 99; j++) 11 b.getInt(); 12 b.clear(); 13 } 14 long endTime = System.currentTimeMillis(); 15 System.out.println("directAccess:" + (endTime - startTime)); 16 } 17 18 // 分配堆内存 19 public static void bufferAccess() { 20 long startTime = System.currentTimeMillis(); 21 ByteBuffer b = ByteBuffer.allocate(500); 22 for (int i = 0; i < 1000000; i++) { 23 for (int j = 0; j < 99; j++) 24 b.putInt(j); 25 b.flip(); 26 for (int j = 0; j < 99; j++) 27 b.getInt(); 28 b.clear(); 29 } 30 long endTime = System.currentTimeMillis(); 31 System.out.println("bufferAccess" + (endTime - startTime)); 32 } 33 34 public static void directAllocate() { 35 long startTime = System.currentTimeMillis(); 36 for (int i = 0; i < 1000000; i++) { 37 ByteBuffer.allocateDirect(1000); 38 } 39 long endTime = System.currentTimeMillis(); 40 System.out.println("directAllocate:" + (endTime - startTime)); 41 } 42 43 public static void bufferAllocate() { 44 long startTime = System.currentTimeMillis(); 45 for (int i = 0; i < 1000000; i++) { 46 ByteBuffer.allocate(1000); 47 } 48 long endTime = System.currentTimeMillis(); 49 System.out.println("bufferAllocate:" + (endTime - startTime)); 50 } 51 52 public static void main(String args[]) { 53 54 bufferAccess(); 55 directAccess(); 56 57 System.out.println(); 58 59 bufferAllocate(); 60 directAllocate(); 61 }
结果:
bufferAccess175 directAccess:134 bufferAllocate:233 directAllocate:634
时间: 2024-12-28 08:15:49