亚洲精品久久久久久第一页-人妻少妇精彩视品一区二区三区-91国产自拍免费视频-免费一级a在线播放视频正片-少妇天天日天天射天天爽-国产大屁股喷水视频在线观看-操美女骚穴抽插性爱视频-亚洲 欧美 中文字幕 丝袜-成人免费无码片在线观看

jvm設(shè)置堆內(nèi)存參數(shù) java heap space解決方法


jvm設(shè)置堆內(nèi)存參數(shù) java heap space解決方法

文章插圖
我們首先了解下什么是JVM 。
JVM(Java Virtual Machine),簡(jiǎn)而言之就是java程序的運(yùn)行環(huán)境(java二進(jìn)制字節(jié)碼的運(yùn)行環(huán)境) 。以下表格比較了JVM、JRE和JDK之間的關(guān)系:
JVMJava Virtual MachineJREJVM+基礎(chǔ)類庫(kù)JDKJVM+基礎(chǔ)類庫(kù)+編譯工具開發(fā)javase程序JDK+IDE工具開發(fā)javaee程序JDK+IDE工具+應(yīng)用服務(wù)器JVM的內(nèi)存可以分為5大塊:程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧、堆以及方法區(qū)
1、程序計(jì)數(shù)器,也稱為寄存器 。我們知道,java程序的執(zhí)行順序是jvm指令->解釋器->機(jī)器碼->CPU,那么程序計(jì)數(shù)器的作用就是在程序執(zhí)行的過(guò)程中,記住下一條JVM指令的執(zhí)行地址 。當(dāng)執(zhí)行完當(dāng)前JVM指令之后,會(huì)在程序計(jì)數(shù)器中獲取到下一條JVM指令的地址,以此去尋找下一條指令 。
要記住,程序計(jì)數(shù)器是每條線程私有的 。當(dāng)線程因?yàn)槟撤N原因暫停執(zhí)行后,該條線程的程序計(jì)數(shù)器會(huì)記錄下條指令的地址,等結(jié)束暫停后,線程可以從停止的地方繼續(xù)執(zhí)行 。而且,程序計(jì)數(shù)器不會(huì)存在內(nèi)存溢出 。
2、虛擬機(jī)棧,就是每個(gè)線程運(yùn)行需要的內(nèi)存空間 。一個(gè)棧由多個(gè)棧幀組成,棧幀對(duì)應(yīng)著每個(gè)方法運(yùn)行時(shí)需要的內(nèi)存(參數(shù),局部變量,返回地址等),每個(gè)線程只能有一個(gè)活動(dòng)棧幀,對(duì)應(yīng)著當(dāng)前正在執(zhí)行的那個(gè)方法 。
當(dāng)方法結(jié)束調(diào)用后,對(duì)應(yīng)的棧幀就會(huì)被移除出棧 。
我們以debug方式運(yùn)行代碼:
查看debug界面可以發(fā)現(xiàn),main、method1和method2方法都以上文的方式被壓入棧中:
所以可以知道,垃圾回收不涉及棧內(nèi)存,因?yàn)榉椒ㄕ{(diào)用完被移除之后,內(nèi)存就會(huì)被釋放掉 。我們可以通過(guò)-Xss設(shè)定棧內(nèi)存的大小,但是請(qǐng)注意,因?yàn)槲覀兊奈锢韮?nèi)存是固定的,所以棧內(nèi)存并不是越大越好,棧內(nèi)存設(shè)置的越大,我們的線程數(shù)量反而越少 。
既然可以分配棧的大小,那么什么情況下會(huì)出現(xiàn)棧內(nèi)存溢出呢?第一種是棧幀過(guò)多導(dǎo)致棧內(nèi)存溢出,第二種就是棧幀過(guò)大導(dǎo)致棧內(nèi)存溢出 。請(qǐng)看如下代碼:
public class Demo1_3 {public static void main(String args[]) {try {m1();}catch (Exception e) {e.printStackTrace();}}private static void m1() {m1();}}由于對(duì)m1進(jìn)行了遞歸調(diào)用,且沒有設(shè)置退出條件,所以運(yùn)行后會(huì)拋出棧內(nèi)存溢出錯(cuò)誤:
Exception in thread "main" java.lang.StackOverflowError這里還有一個(gè)問題,如果多個(gè)線程執(zhí)行m1方法,內(nèi)部的變量x是線程安全的嗎?答案是肯定的,因?yàn)槊總€(gè)線程都有自己的棧,棧內(nèi)的棧幀都會(huì)存在自己的變量x,所以方法內(nèi)的局部變量是線程安全的 。
public class Demo1_2 {static void m1() {int x = 0;for (int i=0; i<5000; i++) {x ++;}System.out.println(x);}}但是如果變量x是每個(gè)方法公有的,那就需要考慮線程安全的問題了,比如用static修飾:
static int x = 0;3、本地方法棧,就是給本地方法的運(yùn)行提供運(yùn)行空間 。本地方法,指那些不是由Java代碼編寫的方法,可以通過(guò)本地方法去調(diào)用解釋器、即時(shí)編譯器或者垃圾回收器 。比如Object類中的clone()方法,真正實(shí)現(xiàn)的是c和c++:
protected native Object clone() throws CloneNotSupportedException;4、堆 。通過(guò)new創(chuàng)建的對(duì)象都會(huì)使用堆內(nèi)存,可以通過(guò)-Xmx設(shè)定堆空間大小 。堆有兩大特點(diǎn),一是線程共享,堆中的對(duì)象都需要考慮線程安全的問題,二是它有垃圾回收機(jī)制 。
我們首先看一下堆內(nèi)存溢出的問題,請(qǐng)看如下代碼:
public class Demo1_4{public static void main(String args[]) {try {List<String> list = new ArrayList<>();String a = "hello";while(true) {list.add(a);a = a + a;}}catch (Exception e) {e.printStackTrace();}}}運(yùn)行后拋出堆內(nèi)存溢出錯(cuò)誤:


以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問題,請(qǐng)您及時(shí)就醫(yī)或請(qǐng)專業(yè)人士給予相關(guān)指導(dǎo)!

「愛刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對(duì)您有所幫助: