圖片描述:java
加載過程當中會先檢查類是否被已加載,檢查順序是自底向上,從Custom ClassLoader到BootStrap ClassLoader逐層檢查,只要某個classloader已加載就視爲已加載此類,保證此類只全部ClassLoader加載一次。而加載的順序是自頂向下,也就是由上層來逐層嘗試加載此類。算法
JVM是基於棧的體系結構來執行class字節碼的。線程建立後,都會產生程序計數器(PC)和棧(Stack),程序計數器存放下一條要執行的指令在方法內的偏移量,棧中存放一個個棧幀,每一個棧幀對應着每一個方法的每次調用,而棧幀又是有局部變量區和操做數棧兩部分組成,局部變量區用於存放方法中的局部變量和參數,操做數棧中用於存放方法執行過程當中產生的中間結果。tomcat
全部經過new建立的對象的內存都在堆中分配,其大小能夠經過-Xmx和-Xms來控制。堆被劃分爲新生代和舊生代,新生代又被進一步劃分爲Eden和Survivor區,最後Survivor由From Space和To Space組成,結構圖以下所示:多線程
每一個線程執行每一個方法的時候都會在棧中申請一個棧幀,每一個棧幀包括局部變量區和操做數棧,用於存放這次方法調用過程當中的臨時變量、參數和中間結果併發
用於支持native方法的執行,存儲了每一個native方法調用的狀態jvm
存放了要加載的類信息、靜態變量、final類型的常量、屬性和方法信息。JVM用持久代(Permanet Generation)來存放方法區,可經過-XX:PermSize和-XX:MaxPermSize來指定最小值和最大值spa
JVM針對新生代和舊生代採用了不一樣的GC線程
新生代一般存活時間較短,所以基於Copying算法來進行回收,所謂Copying算法就是掃描出存活的對象,並複製到一塊新的徹底未使用的空間中,對應於新生代,就是在Eden和From Space或To Space之間copy。指針
新生代採用空閒指針的方式來控制GC觸發,指針保持最後一個分配的對象在新生代區間的位置,當有新的對象要分配內存時,用於檢查空間是否足夠,不夠就觸發GC。server
用java visualVM來查看,能明顯觀察到新生代滿了後,會把對象轉移到舊生代,而後清空繼續裝載,當舊生代也滿了後,就會報outofmemory的異常,以下圖所示:
在執行機制上JVM提供了串行GC(Serial GC)、並行回收GC(Parallel Scavenge)和併發GC(ParNew)。
舊生代與新生代不一樣,對象存活的時間比較長,比較穩定,所以採用標記(Mark)算法來進行回收,所謂標記就是掃描出存活的對象,而後再進行回收未被標記的對象,回收後對用空出的空間要麼進行合併,要麼標記出來便於下次進行分配,總之就是要減小內存碎片帶來的效率損耗。
在執行機制上JVM提供了串行GC(Serial MSC)、並行GC(parallel MSC)和併發GC(CMS)。
你吃飯吃到一半,電話來了,你一直到吃完了之後纔去接,這就說明你不支持併發也不支持並行。
你吃飯吃到一半,電話來了,你停了下來接了電話,接完後繼續吃飯,這說明你支持併發。
你吃飯吃到一半,電話來了,你一邊打電話一邊吃飯,這說明你支持並行。
指定方式 | 新生代GC方式 | 舊生代GC方式 |
---|---|---|
-XX:+UseSerialGC | 串行GC | 串行GC |
-XX:+UseParallelGC | 並行回收GC | 並行GC |
-XX:+UseConeMarkSweepGC | 並行GC | 併發GC |
-XX:+UseParNewGC | 並行GC | 串行GC |
-XX:+UseParallelOldGC | 並行回收GC | 並行GC |
-XX:+ UseConeMarkSweepGC -XX:+UseParNewGC | 串行GC | 併發GC |
不支持的組合 | 一、-XX:+UseParNewGC -XX:+UseParallelOldGC 二、-XX:+UseParNewGC -XX:+UseSerialGC |