類裝載器:加載類文件到內存中,注意類文件並非.java文件,而是.class,是通過javac編譯事後的文件,那類加載器把類加載到內存中,類的元數據信息存在哪裏呢?答案是方法區中。可是類加載器並不負責執行,而是Execution Engine負責執行。java
本地方法棧:本地方法的運行區,那什麼是本地方法呢?本地方法也即native方法,由於Java在剛發佈的時候,那時候是c和c++的世界,因此Java不得不做出一些妥協,兼容c和c++,因此咱們有時看Java代碼,若是是Java程序寫的咱們均可以點進去看看源代碼,可是若是碰到了本地本地方法就沒法點進去看源代碼了。mysql
程序計數器:每一個方法運行的時候,jvm都須要知道這個方法中的字節碼運行到什麼位置了,來決定下一行運行什麼,那就會又一個記錄運行位置的計數器,其實就是一個指針,叫作程序計數器。c++
方法區:Java8中這個東東已經不存在了,在Java8中,在Java8之前叫作永久帶或者叫着方法區,永久帶是在Java的堆內存中的,因此Java8之前堆內存報OOM有兩種,第一種是「OutOfMemoryError:java heap size」,第二種是」OutOfMemoryError: PermGen space」,第二種其實就是永久帶堆內存溢出,那永久帶爲何會溢出呢?若是隻是存放一些類的元數據信息,不至於會內存溢出,真正的緣由是如今不少的Java程序中的不少類都是動態加載,而當動態加載的時候是在方法區中進行的,好比咱們常常在程序中使用的mysql驅動,就是動態加載的。Java8中爲了不這個問題,把元空間直接放到了內存中,理論上來講你內存多大,他均可以使用,不過有參數能夠限制。上面說了一大堆,那元空間中放的是什麼呢?放的是Java8原生自帶的jar包,好比rt.jar等,類的元數據信息,靜態變量,常量。方法區也是有垃圾回收的,GC發現某個類加載器再也不存活了,會把相關的空間整個回收掉。這個垃圾回收的機制是否是堆中的垃圾回收機制相同,不太清楚,沒有找到相關的資料。git
棧:首先明白一點就是棧纔是程序的運行區,伴隨着程序運行的整個生命週期,當程序結束,棧中的數據也會隨之釋放。那棧裏面放的是什麼數據呢?棧裏面放的是棧幀。那棧幀又是什麼東東呢?棧幀就是存放方法運行時方法中的變量和方法的輸入輸出參數,棧的操做,包括出棧和入棧,類文件和方法。棧幀入棧的順序是怎麼的?你們都知道棧是符合「先進後出」的原則的。舉個例子,若是方法A調用了方法B,那方法A會先入棧,以後方法B在入棧,出棧順序恰好相反。以下圖:github
堆:堆是用來存放對象的地方。下面就介紹一下堆的結構和垃圾回收機制:算法
上面是堆空間模型,堆上的GC分爲MinorGC和OldGC,其中MinorGC過程以下。sql
常見的垃圾收集器參考這篇文章:https://crowhawk.github.io/2017/08/15/jvm_3/ 編程
如何判斷某個對象爲垃圾jvm
引用計數法編程語言
目前主流的java虛擬機都摒棄掉了這種算法,最主要的緣由是它很難解決對象 之間相互循環引用的問題。儘管該算法執行效率很高。
例如:在testGC()方法中,對象objA和objB都有字段instance,賦值令objA.instance=objB及objB.instance=objA,除此以外這兩個對象再無任何引用,實際上這兩個對象都已經不能再被訪問,可是它們由於相互引用着對象方,異常它們的引用計數都不爲0,因而引用計數算法沒法通知GC收集器回收它們。
可達性分析算法
前主流的編程語言(java,C#等)的主流實現中,都是稱經過可達性分析(Reachability Analysis)來斷定對象是否存活的。這個算法的基本思路就是經過一系列的稱爲「GC Roots」的對象做爲起始點,從這些節點開始向下搜索,搜索所走過的路徑稱爲引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連(用圖論的話來講,就是從GC Roots到這個對象不可達)時,則證實此對象是不可用的。以下圖所示,對象object 五、object 六、object 7雖然互相有關聯,可是它們到GC Roots是不可達的,因此它們將會被斷定爲是可回收的對象。
經常使用的垃圾回收算法
複製算法
複製算法把內存分爲兩部分,兩部分大小相同,每次只使用其中一個。一塊內存用完後,把活着的對象複製到另外一塊內存,當前內存塊所有回收。這個算法不會產生內存碎片,可是可用內存明顯變少。複製算法把內存分爲兩部分,兩部分大小相同,每次只使用其中一個。一塊內存用完後,把活着的對象複製到另外一塊內存,當前內存塊所有回收。這個算法不會產生內存碎片,可是可用內存明顯變少。複製算法通常應用於新生代。
標記-清除算法
標記-清除算法分爲兩個階段:標記、清除。在標記階段,掃描並標記全部須要回收的對象;在清除階段,統一回收被標記的對象。這個算法的效率並不高,而且清除對象後會產生大量不連續的內存碎片。通常應用於老年代。
標記-整理算法
標記-整理算法與標記-清除算法相似,不一樣的是,不會直接對垃圾對象進行回收,而是把全部存活的對象都移動到一端,而後清理掉其餘部分。通常應用於老年代。
分代收集算法