深入理解JVM虚拟机13:再谈四种引用及GC实践
本文转自互联网,侵删
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
喜欢的话麻烦点下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