java直接内存读取速度为什么快?

直接内存:属于操作系统内存,并不属于java虚拟机内存管理。主要用于NIO()操作时,用于数据缓冲。它的分配回收成本较高,但读写性能高,它不受JVM内存回收管理。

java本身并不具备磁盘读写的能力,如果要调用磁盘读写,必须调用操作系统提供的磁盘函数,也就是native方法,这时候CPU的状态会从java的用户状态,切换到内核状态。


问:直接内存的读写效率为什么比java内存读取快?

核心回答:直接内存读取比java内存读写少了一层缓冲区的读写操作!!!

java内存读操作:
1、java调用操作系统函数读取磁盘资源,操作系统在系统内存中,开辟一块系统缓冲区用于存储读取的资源。
2、系统缓冲区将读取到的资源再次写入到java堆内存中的缓冲区。
3、java对堆内存中的缓冲区进行读取操作。
具体过程如下图:

java内存读取磁盘资源流程

直接内存读取操作:
1、java调用系统函数读取磁盘资源,系统开辟一块直接内存,这块内存系统可以访问,java也可以直接访问。
2、系统函数将资源写入到直接内存中,java直接读取直接内存中资源。
具体流程图如下:

我们通过代码来试验下:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Test6 {

	public static void main(String[] args) throws Exception {
		jianjie(); //java内存读取数据   10799
		zhijie();//直接内存读取数据    9654
	}

	public static void jianjie() throws Exception {
		long startT = System.currentTimeMillis();
		FileInputStream inputStream = new FileInputStream("D://IMG_0020.MP4");
		FileOutputStream outputStream = new FileOutputStream("E://2.mp4");
		byte[] by = new byte[1024 * 1024 * 10];
		while (true) {
			int len = inputStream.read(by);
			if (len == -1) {
				break;
			}
			outputStream.write(by);
		}

		System.out.println("java内存耗时:" + (System.currentTimeMillis() - startT));
	}

	public static void zhijie() throws Exception {
		long startT = System.currentTimeMillis();
		FileChannel inputStream = new FileInputStream("D://IMG_0020.MP4").getChannel();
		FileChannel outputStream = new FileOutputStream("E://1.mp4").getChannel();
		ByteBuffer by = ByteBuffer.allocateDirect(1024 * 1024 * 10);
		while (true) {
			int len = inputStream.read(by);
			if (len == -1) {
				break;
			}
			by.flip();
			outputStream.write(by);
			by.clear();
		}

		System.out.println("直接内存耗时:" + (System.currentTimeMillis() - startT));
	}

}
举报
评论 0