国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

java內(nèi)存區(qū)域與內(nèi)存溢出異常

2019-11-06 06:08:13
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

1 運(yùn)行時(shí)數(shù)據(jù)區(qū)

1.1 程序計(jì)數(shù)器

程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,主要功能是作為當(dāng)前線(xiàn)程所執(zhí)行字節(jié)碼當(dāng)前行號(hào)指示器。當(dāng)其運(yùn)行java方法時(shí),指向的是虛擬機(jī)字節(jié)碼指令的地址,當(dāng)其運(yùn)行native方法時(shí),則為空。程序計(jì)數(shù)器是java虛擬機(jī)規(guī)范中唯一沒(méi)有OutOfMemoryError情況的區(qū)域.

1.2 虛擬機(jī)棧

虛擬機(jī)棧描述的主要是java方法執(zhí)行的內(nèi)存模型,用于存儲(chǔ)方法調(diào)用時(shí)的創(chuàng)建的棧幀,棧幀存儲(chǔ)了局部變量表,操作數(shù)棧,動(dòng)態(tài)連接,方法出口等信息。線(xiàn)程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度時(shí),拋出stackoverflowError異常,如果虛擬機(jī)可以動(dòng)態(tài)擴(kuò)展,但擴(kuò)展時(shí)無(wú)法申請(qǐng)足夠的內(nèi)存,則會(huì)拋出OutOfMemoryError異常。

1.3 本地方法棧

本地方法棧實(shí)現(xiàn)的功能和虛擬機(jī)棧類(lèi)似,不過(guò)它處理的是native方法。

1.4 堆

堆的主要功能是存放對(duì)象實(shí)例,幾乎所有的數(shù)組和對(duì)象實(shí)例都是在堆中分配.并且它也是垃圾回收的主要區(qū)域.如果堆中沒(méi)有內(nèi)存來(lái)分配實(shí)例,并且不能擴(kuò)展,則會(huì)拋出outOfMemoryError

1.5 方法區(qū)

方法區(qū)用于存放已被虛擬機(jī)加載的類(lèi)信息,常量,靜態(tài)變量,即時(shí)編譯編譯后的代碼(動(dòng)態(tài)代理等)等數(shù)據(jù)。當(dāng)方法區(qū)無(wú)法滿(mǎn)足分配需求時(shí),將拋出OutOfMemoyError異常

1.6 直接內(nèi)存

jdk1.4中新加入了NIO類(lèi),引入了一種基于通道與緩沖區(qū)的I/O方式,它可以使用Native函數(shù)直接分配堆外內(nèi)存,然后通過(guò)一個(gè)存儲(chǔ)在java堆中的DirectByteBuffer對(duì)象作為這塊內(nèi)存的引用進(jìn)行操作。這樣避免了java堆和native堆之間來(lái)回復(fù)制數(shù)據(jù),提高了性能。

2 對(duì)象管理

2.1 對(duì)象的創(chuàng)建

虛擬機(jī)遇到一條new指令時(shí),首先將先檢查這個(gè)指令的參數(shù)是否能在常量池中定位到一個(gè)類(lèi)的符號(hào)引用,并且檢查這個(gè)符號(hào)是否被加載,解析,初始化過(guò)。如果沒(méi)有,則執(zhí)行類(lèi)加載過(guò)程。在類(lèi)加載后,就是對(duì)對(duì)象分配內(nèi)存,對(duì)于java內(nèi)存規(guī)整的情況,使用的是"指針碰撞",而不規(guī)整的則采用"空閑列表"的分配方式。經(jīng)過(guò)上面的操作后,執(zhí)行<init>將對(duì)象按照程序員的意愿進(jìn)行初始化。

2.2 對(duì)象的內(nèi)存布局

在hotspot虛擬機(jī)中,對(duì)象的內(nèi)存中的存儲(chǔ)的布局可以分為三個(gè)部分對(duì)象頭 ,實(shí)例數(shù)據(jù)對(duì)齊填充。對(duì)象頭主要有兩部分信息,第一部分為用于存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù),如哈希碼,GC分代年齡,鎖狀態(tài)標(biāo)志,線(xiàn)程持有的鎖,偏向線(xiàn)程ID,偏向時(shí)間戳等。另一部分為類(lèi)型指針,指向類(lèi)的元數(shù)據(jù)信息。對(duì)于數(shù)組還有一部分為數(shù)組長(zhǎng)度信息。實(shí)例數(shù)據(jù)存儲(chǔ)的即為各種類(lèi)型的字段內(nèi)容。

2.3 對(duì)象的訪(fǎng)問(wèn)定位

主要是使用句柄直接指針兩種方式。句柄是java堆中會(huì)分出一塊內(nèi)存來(lái)作為句柄池,reference存儲(chǔ)的是對(duì)象的句柄地址,而句柄中存儲(chǔ)的是對(duì)象數(shù)據(jù)和類(lèi)數(shù)據(jù)地址。直接地址方式是reference直接指向的就對(duì)象地址句柄的優(yōu)勢(shì)是對(duì)象移動(dòng)不用修改reference指針,只需要修改句柄指針,而直接指針的優(yōu)勢(shì)是訪(fǎng)問(wèn)速度更快.

3 OutOfMemoryError異常例子

3.1 堆內(nèi)存溢出

import java.util.ArrayList;import java.util.List;/** * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError * -Xms設(shè)置堆的最小值為20MB * -Xmx設(shè)置堆的最大值為20MB * -XX:+HeapDumpOnOutOfMemoryError內(nèi)存溢出時(shí)dump堆信息 */public class HeapOOM {			static class OOMObject{			}		public static void main(String[] args) {		List<OOMObject> list = new ArrayList<>() ; 		while(true){			list.add(new OOMObject()) ; 		}	}	}
輸出:java.lang.OutOfMemoryError: Java heap spaceDumping heap to java_pid6992.hPRof ...Heap dump file created [27980588 bytes in 0.197 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap space	at java.util.Arrays.copyOf(Unknown Source)	at java.util.Arrays.copyOf(Unknown Source)	at java.util.ArrayList.grow(Unknown Source)	at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)	at java.util.ArrayList.ensureCapacityInternal(Unknown Source)	at java.util.ArrayList.add(Unknown Source)	at com.HeapOOM.main(HeapOOM.java:20)

3.2 虛擬機(jī)棧和本地方法棧溢出

/** * -Xss128k * -Xss設(shè)置堆棧內(nèi)存 * */public class JVMSOF {		private int stackDepth  = 1; 		public void stackLeak(){		stackDepth++ ; 		stackLeak();  	}		public static void main(String[] args) {		JVMSOF jvmsof = new JVMSOF() ; 		try{			jvmsof.stackLeak();  		}catch(Throwable e){			e.printStackTrace();			System.out.println(jvmsof.stackDepth);		}			}}
結(jié)果:986Exception in thread "main" java.lang.StackOverflowError	at com.JVMSOF.stackLeak(JVMSOF.java:13)	at com.JVMSOF.stackLeak(JVMSOF.java:14)	at com.JVMSOF.stackLeak(JVMSOF.java:14)

3.3 方法區(qū)OOM

import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;/** * -XX:PermSize=10M -XX:MaxPermSize=10M * -XX:PermSize設(shè)置方法區(qū)的大小 * 這兩個(gè)參數(shù)在java8中忽略,并且下面代碼在java8后沒(méi)有memoryOutOfError異常 * */public class RuntimeConstantPoolOOM {	public static void main(String[] args) {		while(true){			Enhancer enhancer = new Enhancer() ; 			enhancer.setSuperclass(RCPOOMObject.class);			enhancer.setUseCache(false);			enhancer.setCallback(new MethodInterceptor() {								@Override				public Object intercept(Object obj, Method method, Object[] args,						MethodProxy proxy) throws Throwable {					return proxy.invokeSuper(obj, args); 				}			});			enhancer.create() ; 					}	}		static class RCPOOMObject{			}}
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 仪陇县| 兴宁市| 弥勒县| 哈巴河县| 南通市| 渝中区| 克山县| 岗巴县| 赞皇县| 彭阳县| 化隆| 德江县| 探索| 抚宁县| 靖远县| 通州区| 巴青县| 滨州市| 正镶白旗| 庄浪县| 扎兰屯市| 湖北省| 张北县| 遂平县| 泾川县| 屏东县| 新巴尔虎左旗| 永丰县| 四川省| 沈丘县| 台前县| 安远县| 敦化市| 台东县| 开封市| 玛沁县| 井冈山市| 黔西| 长岛县| 宁明县| 名山县|