根据官方文档的描述: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操做上,仍是有明显的差别的!