JVM內(nèi)存模型
JVM內(nèi)存模型你只要看這一篇就夠了
http://www.itdecent.cn/p/c9ac99b87d56
程序猿的日常——JVM內(nèi)存模型與垃圾回收
https://www.cnblogs.com/xing901022/p/7725961.html


方法區(qū)位置
jdk1.7
方法區(qū)相當(dāng)于永久帶jdk 1.8
元空間(Metaspace)來代替原來的永久帶。
方法區(qū)相當(dāng)于元空間。
不過元空間與永久代之間最大的區(qū)別在于:元空間并不在虛擬機中,而是使用本地內(nèi)存。因此,默認(rèn)情況下,元空間的大小僅受本地內(nèi)存限制,但可以通過參數(shù)來指定元空間的大小。
為什么要移出永久帶:
永久代的大小指定比較困難,太小容易出現(xiàn)永久代溢出,太大則容易導(dǎo)致老年代溢出。
方法區(qū)
存放class類對象:
1.類的基本信息
2.方法信息
3.常量池
4.靜態(tài)變量
- 堆與棧分開設(shè)計是為什么呢?
1.棧存儲了處理邏輯、堆存儲了具體的數(shù)據(jù),這樣隔離設(shè)計更為清晰
2.堆與棧分離,使得堆可以被多個棧共享。
3.棧保存了上下文的信息,因此只能向上增長;而堆是動態(tài)分配
棧的大小可以通過-XSs設(shè)置,如果不足的話,會引起java.lang.StackOverflowError的異常。
垃圾回收
-
堆分代
image.png1.新生代(Young Generation):
用于存放新創(chuàng)建的對象,采用復(fù)制回收方法,如果在s0和s1之間復(fù)制一定次數(shù)后,轉(zhuǎn)移到年老代中。這里的垃圾回收叫做minor GC;
2.年老代(Old Generation):
這些對象垃圾回收的頻率較低,采用的標(biāo)記整理方法,這里的垃圾回收叫做 major GC。
3.永久代(Permanent Generation, 不屬于堆區(qū),可以認(rèn)為是方法區(qū)):
存放Java本身的一些數(shù)據(jù),當(dāng)類不再使用時,也會被回收。 -
新生代垃圾回收過程
當(dāng)觸發(fā)minor GC時,會先把Eden中存活的對象復(fù)制到to Survivor中;
然后再看from survivor,如果次數(shù)達(dá)到年老代的標(biāo)準(zhǔn),就復(fù)制到年老代中;如果沒有達(dá)到則復(fù)制到to survivor中,如果to survivor滿了,則復(fù)制到年老代中。
然后調(diào)換from survivor 和 to survivor的名字,保證每次to survivor都是空的等待對象復(fù)制到那里的。
垃圾收集器
新時代收集器
1.串行收集器 Serial
2.并行收集器 Parallel(并行)
3.ParNew(并行)老年代收集器
1.Serial Old
2.Parallel Old(并行)
3.CMS(并發(fā)標(biāo)記清除收集器 Concurrent Mark Sweep Collector)整堆收集器:G1(Garbage First Collector, 并發(fā))
- 并行(用戶線程仍然處于等待狀態(tài))
指多條垃圾收集線程并行工作,但此時用戶線程仍然處于等待狀態(tài) - 并發(fā)
指用戶線程與垃圾收集線程同時執(zhí)行(但不一定是并行的,可能會交替執(zhí)行);
用戶程序在繼續(xù)運行,而垃圾收集程序線程運行于另一個CPU上;

- Minor GC和Full GC的區(qū)別
- Minor GC
又稱新生代GC,指發(fā)生在新生代的垃圾收集動作;
因為Java對象大多是朝生夕滅,所以Minor GC非常頻繁,一般回收速度也比較快; - Full GC
又稱Major GC或老年代GC,指發(fā)生在老年代的GC;
出現(xiàn)Full GC經(jīng)常會伴隨至少一次的Minor GC(不是絕對,Parallel Sacvenge收集器就可以選擇設(shè)置Major GC策略);
Major GC速度一般比Minor GC慢10倍以上;
- Minor GC
頻繁GC優(yōu)化
- 新生代的垃圾回收模式

由于JVM設(shè)計者認(rèn)為,大部分的對象都是新創(chuàng)建的,生命周期都不長。因此新建的對象會直接放在新生代中,并采用復(fù)制回收機制。即保證to區(qū)總是空的,每次觸發(fā)GC的時候,就會把Eden和from survivor中的還存活的對象拷貝到to區(qū)中。然后to變成了from,from變成to。這樣反復(fù)幾次,還存活的對象,就會拷貝到old老年代當(dāng)中。
在配置JVM的時候就有幾個比較重要的參數(shù):
-Xms 和 -Xmx 配置了堆的最小和最大內(nèi)存
-XX:NewSize 和 -XX:MaxNewSize 配置了新生代的內(nèi)存。最大是Xmx的一半,不過最好還是看業(yè)務(wù)場景
-XX:NewRatio 設(shè)置新生代和老年代的比例,如 -XX:NewRatio=3 指定老年代/新生代為3/1
-XX:SurvivorRatio 設(shè)置survivor與eden的比例,如 -XX:SurvivorRatio=10 表示eden是survivor的10倍,即survivor每個占1/12,eden占10/12
-XX:InitialTenuringThreshold, -XX:MaxTenuringThreshold and -XX:TargetSurvivorRatio 控制進(jìn)入老年代的條件,例如 , -XX:MaxTenuringThreshold=10 -XX:TargetSurvivorRatio=90 設(shè)定老年代閥值的上限為10,幸存區(qū)空間目標(biāo)使用率為90%
-XX:+NeverTenure and -XX:+AlwaysTenure 分別表示永遠(yuǎn)不進(jìn)入老年代,和一次GC存活就進(jìn)入老年代
