好程序員Java教程分享jvm篇

好程序員java教程分享jvm篇,在前面的文章中,介紹了JVM內存模型分爲:堆區、虛擬機棧、方法區、本地方法區和程序計數器,其中堆區是JVM中最大的一塊內存區域,在Java中的全部對象實例都保存在此區域,它能被全部線程共享。html

在Java中還有一個重要的機制:GC(垃圾收集器),堆是GC管理的主要區域,本文會帶你們瞭解GC機制。java


GC的簡介程序員

GC(Garbage Collection)垃圾收集機制是Java一個重要特性。不一樣於C/C++語言須要程序員本身管理內存的回收,並且這樣作每每容易出錯,致使內存泄漏等嚴重問題。算法

Java程序員不用編寫回收內存的代碼,由於Java有GC機制,它是一個特殊的後臺線程,該線程對JVM中的內存進行標記,並肯定哪些須要回收,再經過必定的回收策略自動回收內存,它在後臺一直運行,保證JVM不會出現內存溢出的問題。jvm

對象回收的算法學習

那麼GC是如何判斷某個對象的內存須要回收呢?GC須要判斷該對象已死,也就是再也不被調用,如何判斷對象再也不被調用呢?線程

這裏有兩種算法:3d

一、引用計數算法cdn

二、可達性分析算法htm

引用計數算法

該算法給每一個對象分配一個計數器,當有引用指向這個對象時,計數器加1,當指向該對象的引用失效時,計數器減一。最後若是該對象的計數器爲0時,java垃圾回收器會認爲該對象是可回收的。

優勢:

一、實時性高,只要對象計數器爲0就進行回收,不用等到內存不足的時候。

二、在垃圾回收過程當中,應用無需掛起。

三、更新對象的計數器時,只是影響到該對象,不會掃描所有對象。

缺點:

一、每次引用對象時,都會更新計數器,有時間消耗

二、不能解決循環引用問題

那什麼是循環引用問題呢?咱們看下面這段代碼:

1. class ClassA{

2. ClassB b;

3. }

4. class ClassB{

5. ClassA a;

6. }

7. public static void main(String[] args){

8. ClassA a = new ClassA();

9. ClassB b = new ClassB();

10. a.b = b;

11. b.a = a;

12. a = null;

13. b = null;

14. }

上面的a、b兩個對象雖然都賦值爲null,可是都不能回收,由於存在循環引用,它們的計數器不爲0.

可達性分析算法

該算法經過一種被稱做「GC Root」的對象做爲起始點,從這些節點開始向下搜索,搜索所走過的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈相連時,則證實此對象時不可用的。

以下圖:


在Java語言中,可做爲GC Roots對象包括下面幾種:

1)虛擬機棧中引用的對象

2)方法區中類靜態屬性引用的對象

3)方法區常量池中引用的對象

3)本地方法棧中JNI引用的對象

再回頭看前面這段代碼,雖然a和b對象的引用計數都不爲0,可是它們做爲GC Root對象,最後都賦值爲null,致使引用不可達,這樣兩個對象都是能夠被回收的。


總結

本文咱們學習了JVM中的垃圾收集(GC)機制,GC是一個在後臺持續運行的線程,幫助咱們回收JVM堆中的對象內存,保證JVM不會內存溢出。

如何判斷對象內存須要回收,有兩個算法:引用計數算法和可達性分析算法。

引用計數算法經過判斷對象的引用計數爲0,就標記該對象內存能夠回收,可是不能很好的解決循環引用問題;可達性分析算法經過GC Root向下搜索,若是引用鏈相連則對象可達,不然標記對象不可達,能夠進行回收,這種算法能很好解決對象循環引用問題。

相關文章
相關標籤/搜索