总览

本文会介绍垃圾回收的以下几个方面。

  • 为什么要垃圾回收
  • 在哪里回收
  • 哪些对象需要回收
  • 怎么回收
  • HotSpotJVM中有哪些具体的回收器可以直接用。

在开始讲垃圾回收之前,先通过一张图快速回忆一下运行时内存

为什么需要垃圾回收

  • 因为程序在运行的过程中,对象实例,变量会占据越来越多的内存,如果不及时的清理,会造成性能下降和内存耗尽的问题。

从哪里回收

  • 堆和方法区。堆里面不再使用的对象实例,方法区里面的不再使用的常量和类。

如何判断一个对象需要回收呢?

  • 有两种算法。

    • 引用计数法,就是对象被引用一次就+1, 当引用为0的时候就进行回收。

      这种算法缺点是当两个对象互相引用的时候,就不会被回收。

  • 可达性分析法:通过对象是否能够通过GC ROOT的引用链可达 判断 对象是否可以被回收。

     

   上图就是一个可达性分析的常见场景,对象三什么时候回被回收?先上结果:对象三是软可达,正常情况下在内存不足的时候会被回收。

   这里需要理解两个概念

  • 一个是哪些数据可以作为GC ROOT,虚拟机栈中本地变量表引用的对象

    • 方法区中

      • 类静态变量引用的对象
      • 常量引用的对象
    • 本地方法栈中JNI引用的对象
    • 一个是对象引用有哪几种类型。

       为了更加灵活的控制对象的生命周期,将对象引用分为四个级别。

  • 强引用( Strong Reference ):这是最常见的引用,不会被GC,除非你显示的置为null,才会GC。
Object o=new Object();

  • 软引用( Soft Reference ):用来描述有用但非必须的对象,内存不足的时候回GC,多用于caching/pooling中,比如下面例子网页缓存吃紧的时候回收内存。
SoftReference<String> sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());

  • 弱引用( Weak Reference ):也是用来描述非必须的对象,在下一次GC的时候就会回收,跟内存是否不足无关。
Object obj = new Object();
WeakReference<Object> WeakRef =new WeakReference(obj);
Object objg = WeakRef.get();

  • 虚引用( Phantom Reference ) : 不会影响对象的生命周期,也无法通过虚引用获取对象实例,仅用于在发生GC的时候接受一个系统通知。

    • 必须和引用队列一起使用,主要用来判断对象是否将被垃圾回收器回收。
    • 垃圾回收器准备回收虚引用对象时,会将这个引用加入到与之关联的引用队列中,你通过引用队列判断到某个引用将要被回收就可以立即采取行动。
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
System.out.println(pr.get());

      理解了上面两个概念之后,我们在思考下面一个问题,如果一个对象的引用有多个,怎么通过可达性决定回收周期呢?

      有两个原则。

  • 单条引用链上,由最弱的一个引用类型决定
  • 多条引用链之间,由最强的一个引用类型决定

      上图中对象三是一个软可达对象,因为左半边的链最弱的是弱引用,右边的链最弱的是软引用,左右两边最强的是软引用。

知道了有对象需要回收之后,我们怎么回收呢?有四种方法

  • 标记清除(Mark-Sweep)算法

     先需要回收的对象做标记,之后扫描,将有标记的回收。这种算法效率不高,会产生碎片。最终导致大对象分配空间时无法找到足够大的内存而频繁触发垃圾回收。

  

  • 复制(Copying)算法

     为了解决标记-清除算法碎片的缺点,提出了复制算法,将内存容量按照大小分成两份,每次使用其中的一半,当内存耗尽之后将存活对象有序的复制到另一半中,并清理当前内存。

   这种算法也有缺点:浪费一般空间;效率也跟存活对象多少有关,存活对象多算法效率会将大大降低。

  

  • 标记整理(Mark-Compact)算法

   为了解决复制算法浪费空间的缺点,并利用标记清理的优点,提出了这个算法,就是先标记回收对象,完了之后会将存活对象向同一端移动,然后清理需要回收的对象,这样就保证了空间的连续性。

    

  • 分代收集(Generational Collection)算法

     从回收对象生命周期不同的角度讲内存划分为不同的区域:新生代和老年代,并结合了前面的复制算法和标记整理算法。

  

    新生代中存放的是:新生成的对象实例,也是垃圾回收对象最多的区域,用到的是复制算法。

    老年代会存放的是:在新生代中经历过多次垃圾回收仍然存在的对象;另外新生代生成大对象空间不够时也会在老年代中分配。这里采用的是标记整理算法对老年代区域进行清理。

    其中,新生代又细分为三个区:Eden去,From Survivor区,To Survivor区,比例是8:1:1。

    每次会使用Eden和一块Survivor区(90%新生代内存)服务对象,在触发回收机制时会采用复制算法,将两块区中存活的对象复制到另外10%的内存中,然后清理待回收对象。

这里考虑一个有趣的问题,如果老年代的对象有引用到新生代的,这种情况怎么处理的呢?用的是写屏障,会将这种类型的所有引用都放到一个集合中,标记时需要处理这个集合。

HotSpot JVM基于上面的垃圾回收算法实现的垃圾收集器有哪几种呢?

  • Serial GC/Serial Old GC

    • 两者都属于单线程垃圾收集器,在垃圾收集时,必须暂停所有用户线程。
    • Serial用于新生代,采用复制算法,Serial Old用于老年代,采用标记-整理算法。
  • ParNew GC
    • 是Serial的多线程版本,使用多线程进行垃圾收集。
  • Parallel Scavenge GC/Parallel Old GC
    • 都是吞吐量优先的多线程垃圾收集器
    • Parallel Scavenge GC用于新生代,采用复制算法; Parallel Old GC 用于老年代,采用标记-整理算法。
  • CMS GC
    • Current Mark Sweep,一种以获取最小垃圾回收停顿时间为目标的收集器,并发,采用标记-清除算法。
  • G1 GC基于CMS有不少的改进。基于标记-整理算法,可以比较精确的控制停顿。
  • 具体使用哪种收集器,在JVM中可以通过下面的参数指定。

参考资料:

https://blog.csdn.net/zhangerqing/article/details/8214365

https://blog.csdn.net/wxfx888/article/details/78074145

转载于:https://www.cnblogs.com/darrenqiao/p/9206554.html

Java垃圾回收机制概述相关推荐

  1. 深入理解Java虚拟机:Java垃圾回收机制

    本篇内容包括:JAVA 垃圾回收机制概述.有哪些内存需要回收.如何回收(标记-清除.标记-整理(标记-清除-压缩).复制(标记-复制-清除).分代收集等算法) 以及 何时进行垃圾回收等内容! 一.概述 ...

  2. java垃圾回收机制算法分析

    原文参考:蚂蚁课堂余胜军老师. 垃圾回收机制概述 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存 ...

  3. Java 垃圾回收机制算法分析

    垃圾回收机制算法分析 垃圾回收机制概述 垃圾回收简要过程 手动GC回收 finalize作用 内存泄露 如何防止内存泄露 垃圾回收机制算法 引用计数法 复制算法 标记清除算法 标记-压缩算法 分代收集 ...

  4. java垃圾回收机制_笔记 | Java垃圾回收机制

    本文经授权转载自程序员杂货铺(ID:speakFramework) 垃圾回收 最近上海的小伙伴是不是要被强垃圾分类搞疯了???哈哈哈哈 上海是个走在前列的城市啊,不光骑自行车闯红灯要被罚钱,垃圾不分类 ...

  5. Java垃圾回收机制(Garbage Collection)

    引用博客地址:http://www.cnblogs.com/ywl925/p/3925637.html 以下两篇博客综合描述Java垃圾回收机制 第一篇:说的比较多,但是不详细 http://www. ...

  6. java垃圾回收机制_JVM的垃圾回收机制——垃圾回收算法

    一.Java垃圾回收机制 在java中,程序员是不需要显示的去释放一个对象的内存的,而是由虚拟机自行执行.在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者 ...

  7. 36.JVM内存分哪几个区,每个区的作用是什么、如和判断一个对象是否存活、java垃圾回收机制、垃圾收集的方法有哪些、java类加载过程、类加载机制、双亲委派、Minor GC和Major GC

    36.JVM内存分哪几个区,每个区的作用是什么? 37.如和判断一个对象是否存活?(或者GC对象的判定方法) 38.简述java垃圾回收机制? 39.java中垃圾收集的方法有哪些? 40.java类 ...

  8. 深入理解 Java 垃圾回收机制

    转载自 http://www.cnblogs.com/andy-zcx/p/5522836.html 深入理解 Java 垃圾回收机制 一:垃圾回收机制的意义 java  语言中一个显著的特点就是引入 ...

  9. java垃圾回收机制的理解

    Java垃圾回收机制算法 标记----清除算法 复制算法 标记----整理算法 分代收集算法 为什么要进行垃圾回收 因为当一个对象的引用不可达,或者一个对象没有任何引用指向它,那么它就没有必要在内存中 ...

最新文章

  1. python中全局变量和局部变量关键字_Python中全局变量和局部变量的理解与区别
  2. MYSQL的一些常用函数
  3. 【java设计模式】-00目录
  4. 逸出 java_【java】知识系谱-基础篇-线程-发布、逸出
  5. python画PR曲线(precision-recall曲线)
  6. 使用主题文件(包含CSS文件)时遇到的问题
  7. 第k个数组中的最小值
  8. 如何产生cpk图形_PPK与CPK定义,差异分析及计算
  9. android 自定义时间对话框,android自定义日期和时间选择对话框得实现
  10. 北海焊接机器人_东方自动焊接专机价格优惠
  11. -e mysql_root_password 无效_43万的价格,53万的面子!宝马5系对比奔驰E级
  12. 安装WampServer时出现的问题(丢失VCRUNTIME140.dll或MSVCR110.dll)以及解决办法
  13. Google Earth Engine(GEE)计算湿度(WET)
  14. oracle 还原imp,Oracle学习笔记——imp还原数据库
  15. Istio对接虚拟机
  16. C#编程总结(四)多线程应用(进度条的编程问题)——转自http://www.cnblogs.com/yank/p/3232955.html...
  17. 置换和轮换(新姿势,摘自黑书)
  18. ACM比赛完了后怎么办
  19. 第三人称计算机获奖感言,个人获奖感言50字第三人称
  20. 爬取获取邮箱内容QQ邮箱or163邮箱

热门文章

  1. C语言教程第六章:指针(2)
  2. java简易记账软件_0006JavaSE简单的项目FamilyAccount家庭记账控制台应用程序
  3. 从源码角度解释 fragment 坑(一)
  4. 关于socket组播和ssdp(二)
  5. arm64入栈出栈_【iOS内功】ARM黑魔法—栈桢的入栈和出栈
  6. 【Flink】Flink 周期性 watermark 的 传播 AssignerWithPeriodicWatermarks
  7. 【Elasticsearch】Elasticsearch 动态模板(Dynamic templates)
  8. 【Elasticsearch】Elasticsearch:Searchable snapshot - 可搜索的快照
  9. 【linux】linux shell if 多条件 并行 字符串判断
  10. 60-50-010-API-Kafka producer拦截器(interceptor)