最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java垃圾回收的實現(xiàn)過程

 更新時間:2017年12月14日 14:49:24   投稿:mengwei  
這篇文章主要介紹了淺談Java垃圾回收的實現(xiàn)過程,具有一定借鑒價值,需要的朋友可以參考下。

本教程是為了理解基本的Java垃圾回收以及它是如何工作的。這是垃圾回收教程系列的第二部分。希望你已經(jīng)讀過了第一部分:《簡單介紹Java垃圾回收機制》。

Java垃圾回收是一項自動化的過程,用來管理程序所使用的運行時內(nèi)存。通過這一自動化過程,JVM解除了程序員在程序中分配和釋放內(nèi)存資源的開銷。

啟動Java垃圾回收

作為一個自動的過程,程序員不需要在代碼中顯示地啟動垃圾回收過程。System.gc()和Runtime.gc()用來請求JVM啟動垃圾回收。

雖然這個請求機制提供給程序員一個啟動GC過程的機會,但是啟動由JVM負責。JVM可以拒絕這個請求,所以并不保證這些調(diào)用都將執(zhí)行垃圾回收。啟動時機的選擇由JVM決定,并且取決于堆內(nèi)存中Eden區(qū)是否可用。JVM將這個選擇留給了Java規(guī)范的實現(xiàn),不同實現(xiàn)具體使用的算法不盡相同。

毋庸置疑,我們知道垃圾回收過程是不能被強制執(zhí)行的。我剛剛發(fā)現(xiàn)了一個調(diào)用System.gc()有意義的場景。通過這篇文章了解一下適合調(diào)用System.gc()這種極端情況。

Java垃圾回收過程

垃圾回收是一種回收無用內(nèi)存空間并使其對未來實例可用的過程。

Eden區(qū):當一個實例被創(chuàng)建了,首先會被存儲在堆內(nèi)存年輕代的Eden區(qū)中。

注意:如果你不能理解這些詞匯,我建議你閱讀這篇垃圾回收介紹,這篇教程詳細地介紹了內(nèi)存模型、JVM架構(gòu)以及這些術(shù)語。

Survivor區(qū)(S0和S1):作為年輕代GC(MinorGC)周期的一部分,存活的對象(仍然被引用的)從Eden區(qū)被移動到Survivor區(qū)的S0中。類似的,垃圾回收器會掃描S0然后將存活的實例移動到S1中。

(譯注:此處不應(yīng)該是Eden和S0中存活的都移到S1么,為什么會先移到S0再從S0移到S1?)

死亡的實例(不再被引用)被標記為垃圾回收。根據(jù)垃圾回收器(有四種常用的垃圾回收器,將在下一教程中介紹它們)選擇的不同,要么被標記的實例都會不停地從內(nèi)存中移除,要么回收過程會在一個單獨的進程中完成。

老年代:老年代(Oldortenuredgeneration)是堆內(nèi)存中的第二塊邏輯區(qū)。當垃圾回收器執(zhí)行MinorGC周期時,在S1Survivor區(qū)中的存活實例將會被晉升到老年代,而未被引用的對象被標記為回收。

老年代GC(MajorGC):相對于Java垃圾回收過程,老年代是實例生命周期的最后階段。MajorGC掃描老年代的垃圾回收過程。如果實例不再被引用,那么它們會被標記為回收,否則它們會繼續(xù)留在老年代中。

內(nèi)存碎片:一旦實例從堆內(nèi)存中被刪除,其位置就會變空并且可用于未來實例的分配。這些空出的空間將會使整個內(nèi)存區(qū)域碎片化。為了實例的快速分配,需要進行碎片整理?;诶厥掌鞯牟煌x擇,回收的內(nèi)存區(qū)域要么被不停地被整理,要么在一個單獨的GC進程中完成。

垃圾回收中實例的終結(jié)

在釋放一個實例和回收內(nèi)存空間之前,Java垃圾回收器會調(diào)用實例各自的finalize()方法,從而該實例有機會釋放所持有的資源。雖然可以保證finalize()會在回收內(nèi)存空間之前被調(diào)用,但是沒有指定的順序和時間。多個實例間的順序是無法被預知,甚至可能會并行發(fā)生。程序不應(yīng)該預先調(diào)整實例之間的順序并使用finalize()方法回收資源。

任何在finalize過程中未被捕獲的異常會自動被忽略,然后該實例的finalize過程被取消。

JVM規(guī)范中并沒有討論關(guān)于弱引用的垃圾回收機制,也沒有很明確的要求。具體的實現(xiàn)都由實現(xiàn)方?jīng)Q定。

垃圾回收是由一個守護線程完成的。

對象什么時候符合垃圾回收的條件?

所有實例都沒有活動線程訪問。

沒有被其他任何實例訪問的循環(huán)引用實例。

Java中有不同的引用類型。判斷實例是否符合垃圾收集的條件都依賴于它的引用類型。

引用類型 垃圾收集
強引用(Strong Reference) 不符合垃圾收集
軟引用(Soft Reference) 垃圾收集可能會執(zhí)行,但會作為最后的選擇
弱引用(Weak Reference) 符合垃圾收集
虛引用(Phantom Reference) 符合垃圾收集

在編譯過程中作為一種優(yōu)化技術(shù),Java 編譯器能選擇給實例賦 null 值,從而標記實例為可回收。

class Animal {
  public static void main(String[] args) {
    Animal lion = new Animal();
    System.out.println("Main is completed.");
  }
 
  protected void finalize() {
    System.out.println("Rest in Peace!");
  }
}

在上面的類中,lion對象在實例化行后從未被使用過。因此Java編譯器作為一種優(yōu)化措施可以直接在實例化行后賦值lion=null。因此,即使在SOP輸出之前,finalize函數(shù)也能夠打印出'RestinPeace!'。我們不能證明這確定會發(fā)生,因為它依賴JVM的實現(xiàn)方式和運行時使用的內(nèi)存。然而,我們還能學習到一點:如果編譯器看到該實例在未來再也不會被引用,能夠選擇并提早釋放實例空間。

關(guān)于對象什么時候符合垃圾回收有一個更好的例子。實例的所有屬性能被存儲在寄存器中,隨后寄存器將被訪問并讀取內(nèi)容。無一例外,這些值將被寫回到實例中。雖然這些值在將來能被使用,這個實例仍然能被標記為符合垃圾回收。這是一個很經(jīng)典的例子,不是嗎?

當被賦值為null時,這是很簡單的一個符合垃圾回收的示例。當然,復雜的情況可以像上面的幾點。這是由JVM實現(xiàn)者所做的選擇。目的是留下盡可能小的內(nèi)存占用,加快響應(yīng)速度,提高吞吐量。為了實現(xiàn)這一目標,JVM的實現(xiàn)者可以選擇一個更好的方案或算法在垃圾回收過程中回收內(nèi)存空間。

當finalize()方法被調(diào)用時,JVM會釋放該線程上的所有同步鎖。

GCScope示例程序

Class GCScope {
	GCScope t;
	static int i = 1;
	public static void main(String args[]) {
		GCScope t1 = new GCScope();
		GCScope t2 = new GCScope();
		GCScope t3 = new GCScope();
		// No Object Is Eligible for GC
		t1.t = t2;
		// No Object Is Eligible for GC
		t2.t = t3;
		// No Object Is Eligible for GC
		t3.t = t1;
		// No Object Is Eligible for GC
		t1 = null;
		// No Object Is Eligible for GC (t3.t still has a reference to t1)
		t2 = null;
		// No Object Is Eligible for GC (t3.t.t still has a reference to t2)
		t3 = null;
		// All the 3 Object Is Eligible for GC (None of them have a reference.
		// only the variable t of the objects are referring each other in a
		// rounded fashion forming the Island of objects with out any external
		// reference)
	}
	protected void finalize() {
		System.out.println("Garbage collected from object" + i);
		i++;
	}
	class GCScope {
		GCScope t;
		static int i = 1;
		public static void main(String args[]) {
			GCScope t1 = new GCScope();
			GCScope t2 = new GCScope();
			GCScope t3 = new GCScope();
			// 沒有對象符合GC
			t1.t = t2;
			// 沒有對象符合GC
			t2.t = t3;
			// 沒有對象符合GC
			t3.t = t1;
			// 沒有對象符合GC
			t1 = null;
			// 沒有對象符合GC (t3.t 仍然有一個到 t1 的引用)
			t2 = null;
			// 沒有對象符合GC (t3.t.t 仍然有一個到 t2 的引用)
			t3 = null;
			// 所有三個對象都符合GC (它們中沒有一個擁有引用。
			// 只有各對象的變量 t 還指向了彼此,
			// 形成了一個由對象組成的環(huán)形的島,而沒有任何外部的引用。)
		}
		protected void finalize() {
			System.out.println("Garbage collected from object" + i);
			i++;
		}

GC OutOfMemoryError 的示例程序

GC并不保證內(nèi)存溢出問題的安全性,粗心寫下的代碼會導致 OutOfMemoryError。

import java.util.LinkedList;
import java.util.List;
public class GC {
	public static void main(String[] main) {
		List l = new LinkedList();
		// Enter infinite loop which will add a String to the list: l on each
		// iteration.
		do {
			l.add(new String("Hello, World"));
		}
		while (true);
	}
}

輸出:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
  at java.util.LinkedList.linkLast(LinkedList.java:142)
  at java.util.LinkedList.add(LinkedList.java:338)
  at com.javapapers.java.GCScope.main(GCScope.java:12)

總結(jié)

以上就是本文關(guān)于淺談Java垃圾回收的實現(xiàn)過程的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

相關(guān)文章

  • Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系

    Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系

    這篇文章主要介紹了Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系,文章通過圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考幾種,感興趣的小伙伴可以參考一下
    2022-09-09
  • MyBatis處理mysql主鍵自動增長出現(xiàn)的不連續(xù)問題解決

    MyBatis處理mysql主鍵自動增長出現(xiàn)的不連續(xù)問題解決

    本文主要介紹了MyBatis處理mysql主鍵自動增長出現(xiàn)的不連續(xù)問題解決,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • SpringBoot+Shiro+Redis+Mybatis-plus 實戰(zhàn)項目及問題小結(jié)

    SpringBoot+Shiro+Redis+Mybatis-plus 實戰(zhàn)項目及問題小結(jié)

    最近也是一直在保持學習課外拓展技術(shù),所以想自己做一個簡單小項目,于是就有了這個快速上手 Shiro 和 Redis 的小項目,說白了就是拿來練手調(diào)調(diào) API,然后做完后拿來總結(jié)的小項目,感興趣的朋友一起看看吧
    2021-04-04
  • Java進程cpu頻繁100%問題解決方案

    Java進程cpu頻繁100%問題解決方案

    這篇文章主要介紹了Java進程cpu頻繁100%問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • springboot2.3 整合mybatis-plus 高級功能及用法詳解

    springboot2.3 整合mybatis-plus 高級功能及用法詳解

    這篇文章主要介紹了springboot2.3 整合mybatis-plus 高級功能,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • 深入理解Java的接口與抽象類

    深入理解Java的接口與抽象類

    本文主要介紹java 的接口和抽象類,對接口和抽象類進行介紹對比,深入理解,有需要的小伙伴可以參考下
    2016-07-07
  • SpringBoot Tomcat漏洞修復的解決方法

    SpringBoot Tomcat漏洞修復的解決方法

    本文主要介紹了SpringBoot Tomcat漏洞修復的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-04-04
  • 阿里的Easyexcel讀取Excel文件的方法(最新版本)

    阿里的Easyexcel讀取Excel文件的方法(最新版本)

    這篇文章主要介紹了阿里的Easyexcel讀取Excel文件(最新版本)的方法,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • MyEclipse+Tomcat配置詳解(圖文)

    MyEclipse+Tomcat配置詳解(圖文)

    這篇文章主要介紹了MyEclipse+Tomcat配置詳解(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 如何測試Spring MVC應(yīng)用

    如何測試Spring MVC應(yīng)用

    這篇文章主要介紹了如何測試Spring MVC應(yīng)用,幫助大家更好的理解和使用spring框架,感興趣的朋友可以了解下
    2020-10-10

最新評論

卢龙县| 红桥区| 吐鲁番市| 大宁县| 永兴县| 海淀区| 乐都县| 德惠市| 裕民县| 满洲里市| 屏东县| 辽阳市| 永昌县| 毕节市| 泰顺县| 上饶市| 岳池县| 江都市| 珲春市| 岳普湖县| 黄平县| 集贤县| 定兴县| 通州区| 田林县| 金沙县| 闸北区| 竹北市| 华阴市| 永川市| 司法| 新安县| 土默特左旗| 光泽县| 昭觉县| 天台县| 枣阳市| 长子县| 色达县| 永仁县| 克山县|