哪个更快:Java堆还是本地内存
作者:shenzhang 发布时间:[ 2016/11/2 14:23:29 ] 推荐标签:Java 内存
我们所做的仅仅是把对象的属性放入到Memory中:
public class SomeMemoryObject {
private final static int someLong_OFFSET = 0;
private final static int someInt_OFFSET = 8;
private final static int SIZE = 8 + 4; // one long + one int
private long address;
private final Memory memory;
public SomeMemoryObject(Memory memory) {
this.memory = memory;
this.address = memory.alloc(SIZE);
}
@Override
public void finalize() {
memory.free(address);
}
public final void setSomeLong(long someLong) {
memory.putLong(address + someLong_OFFSET, someLong);
}
public final long getSomeLong() {
return memory.getLong(address + someLong_OFFSET);
}
public final void setSomeInt(int someInt) {
memory.putInt(address + someInt_OFFSET, someInt);
}
public final int getSomeInt() {
return memory.getInt(address + someInt_OFFSET);
}
}
现在我们来看看对两个数组的读写性能:其中一个含有数百万的SomeObject对象,另外一个含有数百万的SomeMemoryObject对象。
// with JIT:
Number of Objects: 1,000 1,000,000 10,000,000 60,000,000
Heap Avg Write: 107 2.30 2.51 2.58
Native Avg Write: 305 6.65 5.94 5.26
Heap Avg Read: 61 0.31 0.28 0.28
Native Avg Read: 309 3.50 2.96 2.16
// without JIT: (-Xint)
Number of Objects: 1,000 1,000,000 10,000,000 60,000,000
Heap Avg Write: 104 107 105 102
Native Avg Write: 292 293 300 297
Heap Avg Read: 59 63 60 58
Native Avg Read: 297 298 302 299
结论:跨越JVM的屏障来读本地内存大约会比直接读Java堆中的内存慢10倍,而对于写操作会慢大约2倍。但是需要注意的是,由于每一个SomeMemoryObject对象所管理的本地内存空间都是独立的,因此读写操作都不是连续的。那么我们接下来来对比下读写连续的内存空间的性能。
访问一大块的连续内存空间
这个测试分别在堆中和一大块连续本地内存中包含了相同的测试数据。然后我们来做多次的读写操作看看哪个更快。并且我们会做一些随机地址的访问来对比结果。
// with JIT and sequential access:
Number of Objects: 1,000 1,000,000 1,000,000,000
Heap Avg Write: 12 0.34 0.35
Native Avg Write: 102 0.71 0.69
Heap Avg Read: 12 0.29 0.28
Native Avg Read: 110 0.32 0.32
// without JIT and sequential access: (-Xint)
Number of Objects: 1,000 1,000,000 10,000,000
Heap Avg Write: 8 8 8
Native Avg Write: 91 92 94
Heap Avg Read: 10 10 10
Native Avg Read: 91 90 94
// with JIT and random access:
Number of Objects: 1,000 1,000,000 1,000,000,000
Heap Avg Write: 61 1.01 1.12
Native Avg Write: 151 0.89 0.90
Heap Avg Read: 59 0.89 0.92
Native Avg Read: 156 0.78 0.84
// without JIT and random access: (-Xint)
Number of Objects: 1,000 1,000,000 10,000,000
Heap Avg Write: 55 55 55
Native Avg Write: 141 142 140
Heap Avg Read: 55 55 55
Native Avg Read: 138 140 138
结论:在做连续访问的时候,Java堆内存通常都比本地内存要快。对于随机地址访问,堆内存仅仅比本地内存慢一点点,并且是针对大块连续数据的时候,而且没有慢很多。
后的结论
在Java中使用本地内存有它的意义,比如当你要操作大块的数据时(>2G)并且不想使用垃圾回收器(GC)的时候。从延迟的角度来说,直接访问本地内存不会比访问Java堆快。这个结论其实是有道理的,因为跨越JVM屏障肯定是有开销的。这样的结论对使用本地还是堆的ByteBuffer同样适用。使用本地ByteBuffer的速度提升不在于访问这些内存,而是它可以直接与操作系统提供的本地IO进行操作。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Java性能测试有哪些不为众人所知的原则?Java设计模式??装饰者模式谈谈Java中遍历Map的几种方法Java Web入门必知你需要理解的Java反射机制知识总结编写更好的Java单元测试的7个技巧编程常用的几种时间戳转换(java .net 数据库)适合Java开发者学习的Python入门教程Java webdriver如何获取浏览器新窗口中的元素?Java重写与重载(区别与用途)Java变量的分类与初始化JavaScript有这几种测试分类Java有哪四个核心技术?给 Java开发者的10个大数据工具和框架Java中几个常用设计模式汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等

sales@spasvo.com