您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)如何理解JVM本地方法棧&堆,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
今天我們一起了解一下關(guān)于本地方法棧和Java堆的相關(guān)知識(shí)。
本地方法棧與Java虛擬機(jī)棧發(fā)揮的作用相同,區(qū)別在于Java虛擬機(jī)棧是為虛擬機(jī)執(zhí)行Java方法服務(wù),而本地方法棧是為虛擬機(jī)執(zhí)行Native方法服務(wù)。
Java堆是虛擬機(jī)管理的最大的一塊內(nèi)存區(qū)域,堆主要用來(lái)存放對(duì)象的實(shí)例。Java堆主要分為:
在絕大數(shù)情況下,對(duì)象都會(huì)被分配在新生代,在經(jīng)歷過(guò)一次新生代回收后,如果對(duì)象還存活那么會(huì)進(jìn)入s0或者s1,每經(jīng)過(guò)一次新生代回收,如果對(duì)象存活那么他的年齡將會(huì)加,當(dāng)對(duì)象的年齡到達(dá)一定的條件時(shí)會(huì)進(jìn)入老年代。當(dāng)然如果對(duì)象非常大,超出了新生代的大小,對(duì)象也有可能直接分配在老年代。
隨著JIT編譯器的發(fā)展以及逃逸分析技術(shù)的成熟,棧上分配、標(biāo)量替換等技術(shù)使得對(duì)象分配在堆中變得不再那么絕對(duì)。
棧上分配是指對(duì)那些線程私有的對(duì)象可以將他們打散分散在棧上,分配在棧上的好處是隨著函數(shù)調(diào)用結(jié)束對(duì)象自動(dòng)銷(xiāo)毀,不需要垃圾回收器的介入,從而提高系統(tǒng)的性能。
棧上分配的基礎(chǔ)是要進(jìn)行逃逸分析,逃逸分析的目的是判斷對(duì)象的作用域是否可能逃出函數(shù)體。
逃逸分析只有在Server模式下才可以啟動(dòng)(這個(gè)作者由于本人Java環(huán)境是Server環(huán)境,沒(méi)有做驗(yàn)證,如果有讀者感興趣,可以使用Client模式啟動(dòng)做一下驗(yàn)證然后截圖留言)。參數(shù)是:
public class EscapeAnalysis {
public static class User {
private int id = 1;
private String name = "xiaoming";
}
public static void alloc() {
User u = new User();
u.id = 5;
u.name = "xiaohong";
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
alloc();
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
執(zhí)行以下命令將源碼文件編譯成字節(jié)碼文件并且運(yùn)行字節(jié)碼
javac -d . EscapeAnalysis.javajava -server -Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC jvm/heap/EscapeAnalysis
由于Java8默認(rèn)開(kāi)啟了逃逸分析,所以我們用-XX:-DoEscapeAnalysis移除逃逸分析看一下效果。
通過(guò)上圖我們發(fā)現(xiàn)由于對(duì)象分配在堆上,但我們指定的最大堆為10m,不夠存儲(chǔ)我們大量User對(duì)象,因此虛擬機(jī)需要不停的進(jìn)行垃圾回收來(lái)釋放堆空間,程序執(zhí)行時(shí)間928ms。
下面我們通過(guò)-XX:-EliminateAllocations將標(biāo)量替換關(guān)閉,也就是說(shuō)不允許對(duì)象打散分配在棧上。
java -server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+PrintGC jvm/heap/EscapeAnalysis
當(dāng)我們關(guān)閉標(biāo)量替換以后,會(huì)發(fā)現(xiàn)對(duì)象依舊不能在棧上分配。
下面讓我們看一下當(dāng)我們打開(kāi)逃逸分析和標(biāo)量替換(允許Use對(duì)象的id和name當(dāng)做局部變量在棧上存儲(chǔ)時(shí))執(zhí)行效果:
java -server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+PrintGC jvm/heap/EscapeAnalysis
通過(guò)上圖可以看出,我們的程序只進(jìn)行了一次垃圾回收,總運(yùn)行時(shí)間5ms,相比之前接近1s中的運(yùn)行時(shí)間性能翻了將近200倍,可見(jiàn)由于棧上分配的優(yōu)化,使得小對(duì)象可以直接分配在棧上,避免了垃圾回收器的介入,大幅度提高了我們程序的性能。
棧上分配需要同時(shí)開(kāi)啟逃逸分析和標(biāo)量替換,Java8 Server模式下這兩個(gè)參數(shù)都是默認(rèn)開(kāi)啟的。
上述就是小編為大家分享的如何理解JVM本地方法棧&堆了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。