1?JVM基本結構
1)類加載器classLoader:在JVM啟動時或者類運行時將需要的.class文件加載到內存中
2)內存區域(運行時數據區): 是在JVM運行的時候操作所分配的內存區
3)執行引擎:負責執行class文件中包含的字節碼指令
4)本地方法接口:主要是調用C/C++實現的本地方法及返回結果
?
?
?
?
?
2?JVM內存結構
1 )? 方法區:用于存儲類結構信息的地方,包括常量池、靜態變量、構造函數等。
2)?Java堆(heap):存儲Java實例或者對象的地方。這塊是gc的主要區域
3) Java棧(stack):Java棧總是和線程關聯的,每當創建一個線程時,JVM就會為這個線程創建一個對應的Java棧。在這個java棧中又會包含多個棧幀,每運行一個方法就創建一個棧幀,用于存儲局部變量表、操作棧、方法返回值等。每一個方法從調用直至執行完成的過程,就對應一個棧幀在java棧中入棧到出棧的過程。所以java棧是線程私有的。
4)程序計數器:用于保存當前線程執行的內存地址,由于JVM是多線程執行的,所以為了保證線程切換回來后還能恢復到原先狀態,就需要一個獨立的計數器,記錄之前中斷的地方,可見程序計數器也是線程私有的
5)本地方法棧:和Java棧的作用差不多,只不過是為JVM使用到的native方法服務的
?
?
?
?
?
3?Java對象引用
Java對象的引用可以分為4類:強引用、軟引用、弱引用和虛引用。
1)強引用:通常可以認為是通過new出來的對象,即使內存不足,GC進行垃圾收集的時候也不會主動回收。
Object obj = new Object();
2)軟引用:在內存不足的時候,GC進行垃圾收集的時候會被GC回收
Object obj = new Object();
SoftReference<Object> softReference = new SoftReference<>(obj);
3)弱引用:無論內存是否充足,GC進行垃圾收集的時候都會回收
Object obj = new Object();
WeakReference<Object> weakReference = new WeakReference<>(obj);
4)虛引用:和弱引用類似,主要區別在于虛引用必須和引用隊列一起使用
Object obj = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomReference = new PhantomReference<>(obj, referenceQueue);
引用隊列:如果軟引用和弱引用被GC回收,JVM就會把這個引用加到引用隊列里,如果是虛引用,在回收前就會被加到引用隊列里。
?
?
?
?
?
?
?
4?GC機制
垃圾收集器一般完成兩件事->檢測出垃圾->回收垃圾
1) 對象的年齡相關知識
對象的年齡,如果在一次垃圾回收過程中有使用該對象的,則將對象年齡加1,否則減1,當計數為0,則進行回收,如果年齡達到一定數字則進入老生代。總的來說內存分配機制主要體現在對象創建之后是否仍在使用,已經不使用的則回收,繼續使用的則對其年齡進行更新,達到一定程度,轉移到年老代。
下圖所示是堆中內存分配示意圖,創建一個對象,首先會在eden區域分配區域,如果內存不夠,就會將年齡大的轉移到Survivor區,當survivor區域存儲不下,則會轉移年老代的。對于一些靜態變量不需要使用對象,直接調用的,則會被放入永生代。一般來說長期存活的對象最終會被存放到年老代,還有一種特殊情況也會被存放到年老代,就是創建大對象時,比如數據這種需要申請連續空間的,如果空間比較大的,則會直接進入年老代
?
2)?垃圾檢測方法
- 引用計數法:給每個對象添加引用計數器,每個地方引用它,計數器就+1,失效時-1。如果兩個對象互相引用時,就導致無法回收
- ?可達性分析算法:以根集對象為起始點進行搜索,如果對象不可達的話就是垃圾對象。根集(Java棧中引用的對象、方法區中常量池中引用的對象、本地方法中引用的對象等。JVM在垃圾回收的時候,會檢查堆中所有對象是否被這些根集對象引用,不能夠被引用的對象就會被垃圾回收器回收。)
?
?
3) 垃圾回收算法
-
標記-清除:首先標記所有需要回收的對象,在標記完成之后統計回收所有被標記的對象,它的標記過程即為上面的可達性分析算法,清除所有被標記的對象,缺點:效率不足,標記和清除效率都不高,空間問題,標記清除之后會產生大量不連續的內存碎片,導致大對象分配無法找到足夠的空間,提前進行垃圾回收。
- ?復制算法:復制算法將可用的內存分成兩份,每次使用其中一塊,當這塊回收之后把未回收的復制到另一塊內存中,然后把使用的清除。這種算法運行簡單,解決了標記-清除算法的碎片問題,但是這種算法代價過高,需要將可用內存縮小一半,對象存活率較高時,需要持續的復制工作,效率比較低 優點:保證了空間的連續性,又避免了大量的內存空間浪費.
- ?標記-整理算法:標記過程與標記-清除的標記一樣,但后續不是對可回收對象進行清理,而是讓所有的對象都向一端移動,然后直接清理掉端邊界以外的內存。樣既可以避免不連續空間出現,還可以避免對象存活率較高時的持續復制。這種算法適合老生代。
- ?分代收集算法:??分代收集算法就是目前虛擬機使用的回收算法,它解決了標記整理不適用于老年代的問題,將內存分為各個年代,在不同年代使用不同的算法,從而使用最合適的算法,新生代存活率低,可以使用復制算法。而老年代對象存活率高,沒有額外空間對它進行分配擔保,所以使用標記整理算法
?