专栏首页xingoo, 一个梦想做发明家的程序员Java直接内存与非直接内存性能测试

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可以是两种类型,一种是基于直接内存(也就是非堆内存);另一种是非直接内存(也就是堆内存)。

对于直接内存来说,JVM将会在IO操作上具有更高的性能,因为它直接作用于本地系统的IO操作。而非直接内存,也就是堆内存中的数据,如果要作IO操作,会先复制到直接内存,再利用本地IO处理。

从数据流的角度,非直接内存是下面这样的作用链:

本地IO-->直接内存-->非直接内存-->直接内存-->本地IO

而直接内存是:

本地IO-->直接内存-->本地IO

很明显,再做IO处理时,比如网络发送大量数据时,直接内存会具有更高的效率。

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之外的,因此它不会占用应用的内存。

所以呢,当你有很大的数据要缓存,并且它的生命周期又很长,那么就比较适合使用直接内存。只是一般来说,如果不是能带来很明显的性能提升,还是推荐直接使用堆内存。

关于直接内存需要注意的,就是上面两点了,其他的关于视图啊、作用链啊,都是使用上的问题了。如果有兴趣,可以参考官方API ( 进去后搜索ByteBuffer,就能看到!),里面有少量的描述!重要的一些用法,还得自己摸索。

使用场景

通过上面的官方文档,与一些资料的搜索。可以总结下,直接内存的使用场景:

  • 1 有很大的数据需要存储,它的生命周期又很长
  • 2 适合频繁的IO操作,比如网络并发场景

申请分配地址速度比较

下面用一段简单的代码,测试下申请内存空间的速度:

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操作上,还是有明显的差异的!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收;而使用的内存是由JVM控制的。 那么,什么时机会进行垃圾...

    用户1154259
  • 记一次线上事故的JVM内存学习

    有过JVM经验的开发者都应该知道,GC是在内存不够时,JVM自动进行的自我救赎(删除不用的数据,释放内存空间)。那么NameNode在什么情况下会进行GC呢?在...

    用户1154259
  • 关于jboss的线程问题+java.lang.outofmemoryError

        近日来,用Jmeter做压力测试。发现,每台客户机使用800个线程组压力倍增。昨天的测试,到了今天下午都没有跑完。 仔细观察了下Jboss的错误日志,发...

    用户1154259
  • Android开发笔记(七十五)内存泄漏的处理

    一直以来以为只有C/C++才存在内存泄漏的问题,没想到拥有内存回收机制的Java也可能出现内存泄漏。C/C++存在指针的概念,程序中需要使用指针变量时,就从...

    用户4464237
  • JDK1.8-Java虚拟机运行时数据区域和HotSpot虚拟机的内存模型

    官方文档中规定的运行时数据区一共就几块: PC计数器, 虚拟机栈, 本地方法栈, 堆区, 方法区, 运行时常量池. 这里的官方规定是说, 如果你要做一个Java...

    java架构师
  • 内存泄漏检测工具

    内存泄漏(memory leak),指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。

    阳光岛主
  • Node.js内存溢出时如何处理?

    Node.js 做密集型运算,或者所操作的数组、对象本身较大时,容易出现内存溢出的问题,这是由于 Node.js 的运行环境依赖 V8 引擎导致的。如果经常有较...

    coder_koala
  • 内存泄漏漫谈

    对于C/C++来说,内存泄漏问题一直是个很让人头痛的问题,因为对于没有GC的语言,内存泄漏的概率要比有GC的语言大得多,同时,一旦发生问题,也严重的多,而且,内...

    腾讯移动品质中心TMQ
  • JVM理解其实并不难!

    在阅读本文之前,先向大家强烈推荐一下周志明的《深入理解 Java 虚拟机》这本书。 前些天面试了阿里的实习生,问到关于 Dalvik 虚拟机能不能执行 clas...

    java思维导图
  • Java 进程占用内存过多,幕后元凶原来是线程太多

    我们当前这个系统和很多的第三方系统做了集成,出问题的就是其中一个三方系统。其实很简单,他们的系统会产生一些个人待办任务,然后待办任务的个数需要推送到我们的 AP...

    古时的风筝

扫码关注云+社区

领取腾讯云代金券