java內(nèi)存區(qū)域與內(nèi)存溢出異常
運(yùn)行時(shí)數(shù)據(jù)區(qū)域
java在運(yùn)行時(shí)主要可以分為兩類,之類是線程獨(dú)享的泣栈,另外就是線程共享的铝量。下面我分別介紹這里面的數(shù)據(jù)區(qū)域
程序計(jì)數(shù)器:
記錄jvm字節(jié)碼指令的地址属百,我自己的理解就是每個(gè)線程在執(zhí)行代碼的時(shí)候秃症,一條命令在字節(jié)碼文件中對應(yīng)一條字節(jié)碼候址,然后你要執(zhí)行下一句指令,就需要知道前一條指令的地址种柑,程序計(jì)數(shù)器就起到記錄這個(gè)指令地址的作用宗雇。需注意,程序計(jì)數(shù)器不會拋出OutOfMemoryError
虛擬機(jī)棧(本地方法棧):
這兩個(gè)區(qū)域大致是差不多的莹规,虛擬機(jī)棧是執(zhí)行java方法,本地方法棧是執(zhí)行native方法(本地方法)泌神。
然后他們是java(native)方法在運(yùn)行時(shí)啟動的良漱,運(yùn)行時(shí)會創(chuàng)建一個(gè)棧幀舞虱,里面包含局部變量表、操作數(shù)棧母市、動態(tài)鏈接等信息矾兜,局部變量表中包含基本數(shù)據(jù)類型、對象引用類型患久,就是我們所說的棧椅寺。方法調(diào)用和結(jié)束其實(shí)是一個(gè)棧幀入棧出棧操作
上面三個(gè)是線程獨(dú)享的
java堆:
這是我們平常所說的堆,幾乎所有的對象實(shí)例都存放在這里蒋失,是GC時(shí)的重點(diǎn)區(qū)域(還有下面提到的方法區(qū))
方法區(qū):
里面存放的是虛擬機(jī)加載得到的類信息返帕,靜態(tài)變量,常量和編譯器編譯后的代碼
常量池:方法區(qū)的一部分篙挽,在之后的class文件結(jié)構(gòu)著重講解
直接內(nèi)存:
又被稱作本地內(nèi)存荆萤,就是在我們的計(jì)算機(jī)里面,為java虛擬機(jī)分配好了一個(gè)運(yùn)行內(nèi)存時(shí)铣卡,然而每個(gè)線程的數(shù)據(jù)是先存放在這個(gè)本地內(nèi)存上的链韭,通過對運(yùn)行內(nèi)存共享而達(dá)到線程間數(shù)據(jù)同步,對線程間可見的目的
內(nèi)存泄露煮落、溢出
內(nèi)存泄露、溢出對于學(xué)習(xí)java虛擬機(jī)來講量淌,真的很重要裙秋,只有懂了這些基礎(chǔ),你才能夠知道java虛擬機(jī)調(diào)優(yōu)時(shí)候?yàn)槭裁匆菢幼觥?/p>
內(nèi)存溢出:說簡單點(diǎn)就是虛擬機(jī)分配的內(nèi)存不夠用了。
內(nèi)存泄露:主要在堆區(qū)發(fā)生扳剿,表現(xiàn)為原先創(chuàng)建的應(yīng)該回收對象不夠被虛擬機(jī)回收耕餐,導(dǎo)致可用的內(nèi)存變得越來越少
接下來講講在配置虛擬機(jī)時(shí)為防止內(nèi)存溢出的幾個(gè)重要參數(shù)
1释簿、-xmx表示分配的最大堆內(nèi)存 -xms表示最小堆內(nèi)存,如果相等表示不允許虛擬機(jī)動態(tài)擴(kuò)展堆內(nèi)存
2夺巩、-xss表示每個(gè)線程分配的棧容量贞让,需注意這里分配越大,越容易出現(xiàn)內(nèi)存溢出柳譬。原因是被堆內(nèi)存喳张,方法區(qū)留下的內(nèi)存大致很固定了,每個(gè)線程分配的棧容量越大美澳,在持續(xù)不斷的線程建立過程中销部,必定導(dǎo)致內(nèi)存不夠用可采用的處理方法:用減少內(nèi)存換取線程
3摸航、-XX:PermSize -MaxPermSize用來設(shè)置最大方法區(qū)內(nèi)存