Direct Memory
直接内存。
直接内存并不属于 jvm
内存,属于操作系统内存。所以图中没有。
- 常见于
NIO
操作时,用于数据缓冲区
- 分配回收成本高,但读写性能强
- 不受
JVM
内存回收管理
copy 速度的比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| package com.redisc;
import lombok.extern.slf4j.Slf4j;
import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.FileChannel;
@Slf4j(topic = "c.Run") public class Run {
static final String FROM = ""; static final String TO = ""; static final int _1MB = 1024 * 1024;
public static void main(String[] args) throws IOException { io(); directionBuffer(); }
private static void directionBuffer() { long start = System.nanoTime(); try (FileChannel from = new FileInputStream(FROM).getChannel(); FileChannel to = new FileOutputStream(TO).getChannel();) { ByteBuffer bb = ByteBuffer.allocateDirect(_1MB); while (true) { int len = from.read(bb); if (len == -1) { break; } bb.flip(); to.write(bb); bb.clear(); } } catch (IOException e) { e.printStackTrace(); } long end = System.nanoTime(); System.out.println("direct 用时" + (end - start) / 1000000); }
private static void io() { long start = System.nanoTime(); try (FileInputStream from = new FileInputStream(FROM); FileOutputStream to = new FileOutputStream(TO);) { byte[] buf = new byte[_1MB]; while (true) { int len = from.read(buf); if (len == -1) { break; } to.write(buf); } } catch (IOException e) { e.printStackTrace(); } long end = System.nanoTime(); System.out.println("io 用时" + (end - start) / 1000000); }
}
|
ByteBuffer
比 byte
快 好几倍。
原理
java
本身不具备磁盘读写能力,如果要调用的话,会根据本地方法区来调用系统指令
- 切换到内核态之后,读取磁盘文件
- 操作系统内存中划出缓冲区,然后把内容逐一读到缓冲区
- 操作系统的缓冲区,
java
并不能直接读取,所以,划出 byte[]
用来接收缓冲区的内容
- 然后内核态,变为用户态,进行读写
- 反复这个过程
direct memory
会分配一块直接内存。ByteBuffer.allocateDirect(_1MB);
,这块内存,系统可以直接访问,java
代码也可以直接访问。