一、jvm內(nèi)存模型圖

二、內(nèi)存模型描述
堆:所有新建對(duì)象都會(huì)在堆中開辟內(nèi)存
方法區(qū)(本地內(nèi)存):存放類信息,方法信息,靜態(tài)變量等數(shù)據(jù)(不設(shè)置默認(rèn)21M,建議最好設(shè)置,且設(shè)置一樣,很多程序因?yàn)樵撝翟O(shè)置問(wèn)題,導(dǎo)致fullGC,fullGC后如果未設(shè)置,則會(huì)自動(dòng)擴(kuò)容
由于調(diào)整元空間的大小需要Full GC,這是非常昂貴的操作,如果應(yīng)用在啟動(dòng)的時(shí)候發(fā)生大量Full GC,通常都是由于永久代或元空間發(fā)生了大小調(diào)整,基于這種情況,一般建議在JVM參數(shù)中將MetaspaceSize和MaxMetaspaceSize設(shè)置成一樣的值,并設(shè)置得比初始值要大,對(duì)于8G物理內(nèi)存的機(jī)器來(lái)說(shuō),一般我會(huì)將這兩個(gè)值都設(shè)置為256M。)
堆和方法區(qū)屬于線程共享
棧(java虛擬機(jī)棧):開啟一個(gè)線程時(shí)建立,棧里面包含 局部變量表(用于存放方法執(zhí)行時(shí)產(chǎn)生的變量)、操作數(shù)棧(執(zhí)行程序操作,比如 加減乘除)、動(dòng)態(tài)鏈接(存放方法的變量,類似于 執(zhí)行方法的內(nèi)存地址,運(yùn)行時(shí)才能解析)、方法出口(方法返回)(默認(rèn)1M)
程序計(jì)數(shù)器:當(dāng)程序執(zhí)行到那個(gè)步驟會(huì)記錄在程序計(jì)數(shù)器(個(gè)人理解,應(yīng)為CPU切換,導(dǎo)致線程被掛起,喚醒時(shí)需要從程序計(jì)數(shù)器中獲取執(zhí)行位置,繼續(xù)執(zhí)行)

本地方法棧:存放native方法執(zhí)行時(shí)的變量等元素(目前基本上用不到,為了java最開始兼容其他程序準(zhǔn)備的)
三、GC
對(duì)象初始化時(shí)先放入Eden區(qū),當(dāng)Eden區(qū)超過(guò)設(shè)置大小時(shí),發(fā)生minor gc,回收不了的對(duì)象,轉(zhuǎn)移到S區(qū),后面再發(fā)生minor gc時(shí),是回收Eden區(qū)和Survivor區(qū)一起,第一次轉(zhuǎn)移到s0,第二次就會(huì)轉(zhuǎn)移到s1區(qū);每個(gè)對(duì)象經(jīng)歷一次GC,則會(huì)在對(duì)象頭中記錄GC年齡,默認(rèn)且最大15,則會(huì)被遷入老年代,當(dāng)老年代到達(dá)設(shè)置大小時(shí),則會(huì)發(fā)生full gc,如果gc回收的內(nèi)存不夠,則會(huì)拋出OOM(內(nèi)存溢出)異常;
每次GC都會(huì)發(fā)生stop the world(工作線程停止工作,防止產(chǎn)生新垃圾),每次JVM調(diào)優(yōu)都是為了減少GC次數(shù)以及時(shí)間
GC時(shí)怎么判斷該對(duì)象是否可以回收,根據(jù)GcRoot引用來(lái)查找,虛擬機(jī)棧和本地方法都可以算是GcRoot的一部分

四、參數(shù)設(shè)置
-Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M
-Xss:每個(gè)線程的棧大小
-Xms:初始堆大小,默認(rèn)物理內(nèi)存的1/64
-Xmx:最大堆大小,默認(rèn)物理內(nèi)存的1/4
-Xmn:新生代大小
-XX:NewSize:設(shè)置新生代初始大小
-XX:NewRatio:默認(rèn)2表示新生代占年老代的1/2,占整個(gè)堆內(nèi)存的1/3。
-XX:SurvivorRatio:默認(rèn)8表示一個(gè)survivor區(qū)占用1/8的Eden內(nèi)存,即1/10的新生代內(nèi)存。
關(guān)于元空間的JVM參數(shù)有兩個(gè):-XX:MetaspaceSize=N和 -XX:MaxMetaspaceSize=N
-XX:MaxMetaspaceSize: 設(shè)置元空間最大值, 默認(rèn)是-1, 即不限制, 或者說(shuō)只受限于本地內(nèi)存大小。
-XX:MetaspaceSize: 指定元空間觸發(fā)Fullgc的初始閾值(元空間無(wú)固定初始大小), 以字節(jié)為單位,默認(rèn)是21M左右,達(dá)到該值就會(huì)觸發(fā)full gc進(jìn)行類型卸載, 同時(shí)收集器會(huì)對(duì)該值進(jìn)行調(diào)整: 如果釋放了大量的空間, 就適當(dāng)降低該值; 如果釋放了很少的空間, 那么在不超過(guò)-XX:MaxMetaspaceSize(如果設(shè)置了的話) 的情況下, 適當(dāng)提高該值。這個(gè)跟早期jdk版本的-XX:PermSize參數(shù)意思不一樣,-XX:PermSize代表永久代的初始容量。