首页 > 技术文章 > 深入理解JVM虚拟机13:再谈四种引用及GC实践

AliCoder 2019-11-14 21:50 原文

本文转自互联网,侵删

本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看

https://github.com/h2pl/Java-Tutorial

喜欢的话麻烦点下Star哈

文章将同步到我的个人博客:

www.how2playlife.com

本文是微信公众号【Java技术江湖】的《深入理解JVM虚拟机》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。

该系列博文会告诉你如何从入门到进阶,一步步地学习JVM基础知识,并上手进行JVM调优实战,JVM是每一个Java工程师必须要学习和理解的知识点,你必须要掌握其实现原理,才能更完整地了解整个Java技术体系,形成自己的知识框架。

为了更好地总结和检验你的学习成果,本系列文章也会提供每个知识点对应的面试题以及参考答案。

如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。

一、背景

Java的内存回收不需要程序员负责,JVM会在必要时启动Java GC完成垃圾回收。Java以便我们控制对象的生存周期,提供给了我们四种引用方式,引用强度从强到弱分别为:强引用、软引用、弱引用、虚引用。

二、简介

1.强引用 StrongReference

StrongReference是Java的默认引用形式,使用时不需要显示定义。任何通过强引用所使用的对象不管系统资源有多紧张,Java GC都不会主动回收具有强引用的对象。

public class StrongReferenceTest {

	public static int M = 1024*1024;

	public static void printlnMemory(String tag){
		Runtime runtime = Runtime.getRuntime();
		int M = StrongReferenceTest.M;
		System.out.println("\n"+tag+":");
		System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)");
	}

	public static void main(String[] args){
		StrongReferenceTest.printlnMemory("1.原可用内存和总内存");

		//实例化10M的数组并与strongReference建立强引用
		byte[] strongReference = new byte[10*StrongReferenceTest.M];
		StrongReferenceTest.printlnMemory("2.实例化10M的数组,并建立强引用");
		System.out.println("strongReference : "+strongReference);

		System.gc();
		StrongReferenceTest.printlnMemory("3.GC后");
		System.out.println("strongReference : "+strongReference);

		//strongReference = null;后,强引用断开了
		strongReference = null;
		StrongReferenceTest.printlnMemory("4.强引用断开后");
		System.out.println("strongReference : "+strongReference);

		System.gc();
		StrongReferenceTest.printlnMemory("5.GC后");
		System.out.println("strongReference : "+strongReference);
		}
}

运行结果:

2.弱引用 WeakReference

如果一个对象只具有弱引用,无论内存充足与否,Java GC后对象如果只有弱引用将会被自动回收。

public class WeakReferenceTest {

	public static int M = 1024*1024;

	public static void printlnMemory(String tag){
		Runtime runtime = Runtime.getRuntime();
		int M = WeakReferenceTest.M;
		System.out.println("\n"+tag+":");
		System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)");
	}

	public static void main(String[] args){  
		WeakReferenceTest.printlnMemory("1.原可用内存和总内存");

		//创建弱引用
		WeakReference

推荐阅读