日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

哪个更快:Java 堆还是本地内存

發(fā)布時(shí)間:2025/3/21 java 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哪个更快:Java 堆还是本地内存 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用Java的一個(gè)好處就是你可以不用親自來管理內(nèi)存的分配和釋放。當(dāng)你用new關(guān)鍵字來實(shí)例化一個(gè)對(duì)象時(shí),它所需的內(nèi)存會(huì)自動(dòng)的在Java堆中分配。堆會(huì)被垃圾回收器進(jìn)行管理,并且它會(huì)在對(duì)象超出作用域時(shí)進(jìn)行內(nèi)存回收。但是在JVM中有一個(gè)‘后門’可以讓你訪問不在堆中的本地內(nèi)存(native memory)。在這篇文章中,我會(huì)給你演示一個(gè)對(duì)象是怎樣以連續(xù)的字節(jié)碼的方式在內(nèi)存中進(jìn)行存儲(chǔ),并且告訴你是應(yīng)該怎樣存儲(chǔ)這些字節(jié),是在Java堆中還是在本地內(nèi)存中。最后我會(huì)就怎樣從JVM中訪問內(nèi)存更快給一些結(jié)論:是用Java堆還是本地內(nèi)存。

使用Unsafe來分配和回收內(nèi)存

sun.misc.Unsafe可以讓你在Java中分配和回收本地內(nèi)存,就像C語(yǔ)言中的malloc和free。通過它分配的內(nèi)存不在Java堆中,并且不受垃圾回收器的管理,因此在它被使用完的時(shí)候你需要自己來負(fù)責(zé)釋放和回收。下面是我寫的一個(gè)使用Unsafe來管理本地內(nèi)存的一個(gè)工具類:

public class Direct implements Memory {private static Unsafe unsafe;private static boolean AVAILABLE = false;static {try {Field field = Unsafe.class.getDeclaredField("theUnsafe");field.setAccessible(true);unsafe = (Unsafe)field.get(null);AVAILABLE = true;} catch(Exception e) {// NOOP: throw exception later when allocating memory}}public static boolean isAvailable() {return AVAILABLE;}private static Direct INSTANCE = null;public static Memory getInstance() {if (INSTANCE == null) {INSTANCE = new Direct();}return INSTANCE;}private Direct() {}@Overridepublic long alloc(long size) {if (!AVAILABLE) {throw new IllegalStateException("sun.misc.Unsafe is not accessible!");}return unsafe.allocateMemory(size);}@Overridepublic void free(long address) {unsafe.freeMemory(address);}@Overridepublic final long getLong(long address) {return unsafe.getLong(address);}@Overridepublic final void putLong(long address, long value) {unsafe.putLong(address, value);}@Overridepublic final int getInt(long address) {return unsafe.getInt(address);}@Overridepublic final void putInt(long address, int value) {unsafe.putInt(address, value);}}

在本地內(nèi)存中分配一個(gè)對(duì)象
讓我們來將下面的Java對(duì)象放到本地內(nèi)存中:

public class SomeObject {private long someLong;private int someInt;public long getSomeLong() {return someLong;}public void setSomeLong(long someLong) {this.someLong = someLong;}public int getSomeInt() {return someInt;}public void setSomeInt(int someInt) {this.someInt = someInt;}}

我們所做的僅僅是把對(duì)象的屬性放入到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 intprivate long address;private final Memory memory;public SomeMemoryObject(Memory memory) {this.memory = memory;this.address = memory.alloc(SIZE);}@Overridepublic 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);}}

現(xiàn)在我們來看看對(duì)兩個(gè)數(shù)組的讀寫性能:其中一個(gè)含有數(shù)百萬的SomeObject對(duì)象,另外一個(gè)含有數(shù)百萬的SomeMemoryObject對(duì)象。

// 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

訪問一大塊的連續(xù)內(nèi)存空間

結(jié)論:跨越JVM的屏障來讀本地內(nèi)存大約會(huì)比直接讀Java堆中的內(nèi)存慢10倍,而對(duì)于寫操作會(huì)慢大約2倍。但是需要注意的是,由于每一個(gè)SomeMemoryObject對(duì)象所管理的本地內(nèi)存空間都是獨(dú)立的,因此讀寫操作都不是連續(xù)的。那么我們接下來就來對(duì)比下讀寫連續(xù)的內(nèi)存空間的性能。

這個(gè)測(cè)試分別在堆中和一大塊連續(xù)本地內(nèi)存中包含了相同的測(cè)試數(shù)據(jù)。然后我們來做多次的讀寫操作看看哪個(gè)更快。并且我們會(huì)做一些隨機(jī)地址的訪問來對(duì)比結(jié)果。

// 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

結(jié)論:在做連續(xù)訪問的時(shí)候,Java堆內(nèi)存通常都比本地內(nèi)存要快。對(duì)于隨機(jī)地址訪問,堆內(nèi)存僅僅比本地內(nèi)存慢一點(diǎn)點(diǎn),并且是針對(duì)大塊連續(xù)數(shù)據(jù)的時(shí)候,而且沒有慢很多。

最后的結(jié)論

在Java中使用本地內(nèi)存有它的意義,比如當(dāng)你要操作大塊的數(shù)據(jù)時(shí)(>2G)并且不想使用垃圾回收器(GC)的時(shí)候。從延遲的角度來說,直接訪問本地內(nèi)存不會(huì)比訪問Java堆快。這個(gè)結(jié)論其實(shí)是有道理的,因?yàn)榭缭絁VM屏障肯定是有開銷的。這樣的結(jié)論對(duì)使用本地還是堆的ByteBuffer同樣適用。使用本地ByteBuffer的速度提升不在于訪問這些內(nèi)存,而是它可以直接與操作系統(tǒng)提供的本地IO進(jìn)行操作。

總結(jié)

以上是生活随笔為你收集整理的哪个更快:Java 堆还是本地内存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。