非直接缓冲区
1.分配在java 堆内存中
2.分配非直接缓冲区要比分配直接缓冲区的效率跟高
3.非直接缓冲区需要进行垃圾回收,如果处理不当的话,会对性能造成影响
直接缓存区
非直接缓冲区的特点
1.非直接缓存区是在java 堆内存之外分配,直接在本地内存中分配。
2.分配直接缓冲区比分配非直接缓冲区更加昂贵,效率更低
3.它是直接和本地I/O操作接口,在某些I/O繁重的情况下,可以带来更好的性能
4.不存在在 java 堆内存中,能够减少jvm 垃圾回收器的负担。
java如何分配直接缓存区和非直接缓存区?
查看jdk API doc 发现,这有ByteBuffer 中可以有分配直接缓冲区的方法,那么为什么其它Buffer中没有呢,没有的话其它数据类型如何可以操作直接内存呢?
使用 ByteBuffer 中的方法分配直接缓冲区和非直接缓冲区
public static void main(String[] args) {
// 分配非直接缓冲区 10
ByteBuffer buffer = ByteBuffer.allocate(10);
// 分配非直接缓冲区 10
ByteBuffer directBuffer = ByteBuffer.allocateDirect(10);
}
非直接内存分配方法内部实现
直接内存分配方法内部实现
那么其它的基本数据类型的缓冲区如何可以操作直接内存呢?
public static void main(String[] args) {
ByteBuffer buffer = ByteBuffer.allocate(10);
ByteBuffer directBuffer = ByteBuffer.allocateDirect(10);
// 在 ByteBuffer 中有一系类的 asxxxBuffer() 的方法,将ByteBuffer 直接缓冲区
// 装换为其它基本数据类型的直接缓存区
LongBuffer longBuffer = directBuffer.asLongBuffer();
}
直接缓存区和非直接缓存区的性能测试对比
分配缓冲区对比
package NIO.buffer;
import java.nio.ByteBuffer;
public class TestBuffer {
public static final String str = "hello world";
public static void main(String[] args) {
testBuffer(100000);
testDirectBuffer(100000);
}
private static void testBuffer(int count) {
long start = System.currentTimeMillis();
// ByteBuffer allocate = ByteBuffer.allocate(str.length() * count);
for (int i = 0; i < count; i++) {
ByteBuffer allocate = ByteBuffer.allocate(count);
// allocate.put(str.getBytes());
}
// allocate.flip();
// for (int i = 0; i < count; i++) {
// allocate.getChar();
// }
long end = System.currentTimeMillis();
System.out.println("时间" + (end - start));
}
private static void testDirectBuffer(int count) {
long start = System.currentTimeMillis();
// ByteBuffer allocate = ByteBuffer.allocateDirect(str.length() * count);
for (int i = 0; i < count; i++) {
ByteBuffer allocate = ByteBuffer.allocateDirect(count);
// allocate.put(str.getBytes());
}
// allocate.flip();
// for (int i = 0; i < count; i++) {
// allocate.getChar();
// }
long end = System.currentTimeMillis();
System.out.println("时间" + (end - start));
}
}
结果:
时间2031
时间21933
I/O 对比
package NIO.buffer;
import java.nio.ByteBuffer;
public class TestBuffer {
public static final String str = "hello world";
public static void main(String[] args) {
// 结果:时间8325
// 结果:时间8026
testBuffer(100000000);
testDirectBuffer(100000000);
}
private static void testBuffer(int count) {
long start = System.currentTimeMillis();
ByteBuffer allocate = ByteBuffer.allocate(str.length() * count);
for (int i = 0; i < count; i++) {
allocate.put(str.getBytes());
}
allocate.flip();
for (int i = 0; i < count; i++) {
allocate.getChar();
}
long end = System.currentTimeMillis();
System.out.println("时间" + (end - start));
}
private static void testDirectBuffer(int count) {
long start = System.currentTimeMillis();
ByteBuffer allocate = ByteBuffer.allocateDirect(str.length() * count);
for (int i = 0; i < count; i++) {
allocate.put(str.getBytes());
}
allocate.flip();
for (int i = 0; i < count; i++) {
allocate.getChar();
}
long end = System.currentTimeMillis();
System.out.println("时间" + (end - start));
}
}
结果:
1.两个方法一起执行:
// 结果: 时间8464
// 结果: 时间62052.先后执行
// 结果:时间8325
// 结果:时间8026
总结:
1.非直接内存分配缓冲区的时间小于直接缓冲区的分配时间
2.在I/O 反面 直接缓冲区的效率要比非直接缓冲区的效率跟高
在对比两个东西的效率的时候,我们有时候就会陷入到单一的思维中,就是那个效率跟高,那个更好,其实这个是不对的(我最开始就是这样想的),需要全面的考虑和了解,才能够下判断和决策,选择对应的工具(方法)来解决具体(实际碰到)的问题。
参考:https://www.cnblogs.com/xing901022/p/5243657.html?spm=a2c6h.12873639.article-detail.8.3045438fuWfOLb