1. 程式人生 > >JVM記憶體——類載入——GC回收

JVM記憶體——類載入——GC回收

https://www.cnblogs.com/fefjay/p/6305499.html
https://www.cnblogs.com/protected/p/6419217.html
https://blog.csdn.net/super_YC/article/details/71439786
https://www.cnblogs.com/fanjie/p/6916784.html
http://www.importnew.com/25295.html

JVM記憶體區域

用自己的簡單的語言來總結下JVM的記憶體區域
總的來說分為執行緒共享區和執行緒私有區

執行緒共享區有兩個部分

1.堆:主要用來存放物件例項,也是GC管理的主要區域
2.方法區:已載入類的資訊,常量,靜態量都存在這

執行緒私有區

1.虛擬機器方法棧:生命週期與執行緒相同,裡面由方法對應的棧楨構成,棧楨裡面有區域性變數、常量池引用,運算元棧等。
和物件引用
2.本地方法棧:服務於Native方法,提供本地方法介面
3.程式計數器:用來存放執行緒的下一個位元組碼指令,執行緒的恢復,跳轉等也依賴於他

類的編譯、載入、執行過程

其中載入又分為 類的載入、連線和初始化,連線分為驗證、準備、解析。

javac main.java

類的編譯主要將java檔案編譯為.class檔案,主要生成常量池和方法位元組碼,常量池裡面是一些常量,符號引用等。

然後

java main

此時才啟動jvm程序,jvm從classpath路徑下面找到main.class利用bootstrap classloader類載入器,將main.class載入到方法區去中,

然後進行驗證,主要是驗證.class檔案的格式是否符合java和jvm的規範要求,

然後是準備階段,為靜態變數分配記憶體(對於靜態變數的位置:java只有靜態成員變數,沒有static int,所以它是屬於類的成員,所以位於方法區),初始化為系統預設值(此時不載入靜態程式碼塊)

解析階段:將符號引用轉化為直接引用,直接引用即指向方法的地址。

最後初始化:首先初始化類的靜態變數和靜態程式碼塊。而例項類,只有在java對類的主動使用的時候才會初始化。

主動使用:

1 建立類的例項
2 訪問某個類或介面的靜態變數,或者對該靜態變數賦值
3 呼叫類的靜態方法
4 反射(如Class.forName
(“com.shengsiyuan.Test”)) 5 初始化一個類的子類(先初始化所有的父類,最後初始化本身,介面 除外,類初始化的時候,它所實現的介面不會初始化,就算字介面初始化, 父介面也不會初始化,只有當程式呼叫介面的靜態變數的時候才會導致 介面的初始化) 6 Java虛擬機器啟動時被標明為啟動類的類(即擁有main方法類,對應文 件名的類)

類的載入的最終產品是位於堆區中的Class 物件(即不包括觸發類的主動使用)
Class物件封裝了類在方法區內的資料結構,並且向Java程式設計師提供了訪問方法區內的資料結構的介面

最後類執行,由位元組碼轉為機器碼,在作業系統上面呼叫

gc回收

https://blog.csdn.net/xushuzhan/article/details/78522242
這篇講的比較簡單清晰

1 哪些物件可以被回收

1.1 引用計數法:引用一次+1,失效一次-1,直至為0
1.2 根搜尋演算法:如果一個物件和根物件之間沒有引用關係,那麼就可以回收

2.gc演算法
均是基於根搜尋的思想而實現

2.1 標記清除:遍歷所有物件進行標記,清除未被標記的;記憶體利用率高,但是要遍歷所有物件,耗費資源
這裡寫圖片描述

2.2 複製演算法:把記憶體分為活動和空閒區域,將活動區域標記的物件複製到空閒區域,按照記憶體排放物件。記憶體整齊,但需要2倍記憶體
這裡寫圖片描述

2.3 標記整理:以上兩種演算法的結合,標記後,複製到gc空間
這裡寫圖片描述

2.4 分代回收:即現在jvm使用的演算法
這裡寫圖片描述

新生代區域當GC來的時候,遵循的機制是:
1.當eden區觸發GC,會將內容複製到s0,並清除eden區的內容
2.當s0區域中觸發GC,會將內容複製到s1區域,並清除s1的內容
3.當s1區域觸發GC,會將從s0複製過來且GC後還存活的複製到老年代中,並清空s1

GC發生的時間:這裡是根據記憶體剩餘和演算法來決定什麼時候觸發GC,不一定要記憶體全滿才觸發,且這裡說的是Minor GC,也就是用的快速回收演算法實現的高效率GC,這種方法只對新生代回收。

老年代:老年代裡面存放的都是從新生代複製過來的,且經過了多次GC後依舊存活的物件,如果老年代滿了,則會觸發FULL GC,清除新生代、老年代和永久代的內容,但是效率低。

永久帶:裡面存放的靜態變數和靜態方法。這裡一般不GC,但一旦滿了,也會FULL GC。

回收型別
部分回收和full gc

可以通過對老年代等記憶體的分配來進行記憶體調優,使得回收次數減少,優化資源。

3.記憶體分配

1.物件優先在eden區域分配:如果沒有空間,則觸發一次Minor Gc
2.大物件直接放入老年代:大物件指的是陣列、很長的字串等,為了
避免開銷過大,直接放入老年代
3.長期存活的物件將會放入老年代: 每當物件熬過一次GC,那麼它的age+1,
系統預設當這個數大於15的時候(可修改),它會進入老年代
4.動態物件年齡判斷:如果在Survivor區域,當其中年齡相同的所有物件的數量
大小大於該區域中的一半的時候,年齡大於或等於該年齡的物件將會直接進入老年代。

。。。。未完。。。