Java与C++很大的一个不同点就是Java有自己的垃圾回收系统,可以让程序员在清理垃圾方面不必下过多的功夫。

垃圾回收系统主要分为三部分

1.判别那些对象是垃圾

2.垃圾怎么进行回收

3.什么时候回收垃圾

关于1和2大多数人都知道,判别垃圾的可达性算法和垃圾回收的分代收集法这些大家都有自己的理解了,但是虚拟机究竟是什么时候进行垃圾回收呢?笔者通过这几天的读书,对这方面的知识做了自己的总结。

什么时候GC

首先来说什么时候发生GC(垃圾回收),一下想到的肯定是:内存不够用了就清理一下呗。的确大体上是这样的,我们从虚拟机的角度来理解这个问题,当进行垃圾回收的时候肯定会先进行可达性算法的遍历,这时肯定是要所有的线程的停下来等待可达性算法线程标记对象的,这个过程被称为“Stop The World”,名字很帅啊。

究竟是什么类型的数据

继续往下说之前,先说一下Java中数据的两大分类吧,分别是基本类型和引用类型,这两个类型的数据虽然都是放在堆上的,但是在调用时的行为截然不同啊,于是Java虚拟机利用一个称为OopMap的数据类型去记录哪些变量是基本类型,哪些变量是引用类型,而且也会在特定的位置记录这些信息。

由于垃圾回收时对两种数据类型的操作是不同的,所以Java垃圾回收机肯定要知道现在回收的这个对象究竟是引用还是基本类型,上文说Java虚拟机会把区分对象类型的信息记录在特定的位置,所以在垃圾回收时必须要在这个特定位置进行(这样才能得到对象的类型信息)。这个特定位置被称为“安全点”。

安全点在哪里,有多少

说到这里脑中会产生一个想法:

Java垃圾回收进行的还是比较频繁的(尤其是Minor GC),所以“安全点”应该基本是处处存在的啊,这样才能在发生GC时提供“服务”。

错!如果处处都有安全点去记录信息,那么内存的开销会变得非常大,但是如果安全点过于少的话也不行啊,GC都发生很长时间了,但是就因为无法得到数据类型信息一直无法继续前行。所以“安全点”的位置和出现次数是非常讲究的,“安全点”的选定是根据“是否具有让程序长时间执行的特征”来决定的。Java虚拟机是通过执行一条条指令来运作的(安全点也是记录到某一条的指令上),指令执行都是非常快的(不然我们也不会有那么流畅的体验啊!),所以长时间让程序执行的指令一般是那些方法调用,循环跳转,异常跳转等,这些操作会花一些相对较长的时间而且基本不会产生新的对象,也就是这段时间整个线程的对象总数基本是确定的,所以在这个时间点进行GC是比较理想的。

GC信号与安全点

继续我们的GC流程,内存不够了,Java虚拟机开始发生GC。这时Java虚拟机会发出一个GC,告诉每个线程“发生GC了,赶紧在最近的安全点停下来去回收垃圾”这个信息。然后各个线程都注意到了这个信息,于是在各自的安全点回收当前线程的垃圾对象。问题又来啦!

A:线程是怎么发现GC信号的呢?

B:当然是在执行过程中去实时检测GC信号的啊

A:那要是总检测GC信号,也太浪费资源了吧!

B:当然是在特定的位置检测了

没错,检测的位置就是就是“安全点”,每次Java虚拟机执行到标记为安全点的指令时都会进行一次GC信号检测,如果没有就继续跑指令了,如果有就直接进行GC,反正现在的位置就是安全点,执行GC没毛病(真是佩服那些设计者们,想出这么巧妙的方法)。

在GC信号发出时,各个线程运行到“安全点”就会发现信号,然后停止线程进行GC操作,当所有的线程都回收完毕时,这次GC就结束了。

线程正在执行各自的任务,这时发生了GC,Java虚拟机发出GC信号。

各个线程到了“安全点”,检测到了GC信号,开始进行GC。

每个线程都完成垃圾回收,整个GC结束,各个线程恢复执行。

阻塞呢,无法检测“安全点”

还有一个问题,当程序在等待io操作,或者在sleep的状态怎么办呢?这时程序无法继续向下执行,不能实时检测GC信号,这次GC是不是就错过了?

当然不会啊,有一个特殊的“安全点”可以解决这个问题。

安全区域
如果说安全点是一个“点”,那么“安全区域”就是把这个点进行一个拉长操作,变成一条线,在这条线包含那一片区域就是“安全区域”。

等待io等线程阻塞非常适合放到“安全区域”中,因为在这段时间中,线程就是处于一个等待的状态,基本不会产生新的对象,适合去进行GC。当线程进入“安全区域”时,会把给自己贴上一个安全标签,告诉虚拟机自己现在在“安全区域”,随时可以进行GC。这时发生GC,虚拟机看到这个线程有安全标签,根本就不会管他,直接就是一顿GC全家桶伺候。这时的GC可以说这个线程是不知情的(因为线程在阻塞啊,处于专注的等待状态或者睡得正香),所以当这个线程重新跑以来以后,在它走出安全区时会检测一下虚拟机是不是在GC的过程中,如果是就等待GC完成,如果不是就直接继续运行(管你GC完成了还是压根没GC,反正我已经给过你机会了)。

“安全区”和“安全区域”基本上可以解决所以的问题,所以在GC什么时候进行这一块也就结束了。

线程在安全区域外正常执行

线程执行到安全区域,标记当前线程为安全状态,然后进入了io阻塞

这时发生GC,Java虚拟机查询线程的安全标志,发现此线程处于安全区域,于是直接开始GC。

GC完成,线程从阻塞态变为运行态重新开始运行,走出安全区域时,检测是否有GC在执行中,并没有发现,于是走出安全区域继续执行下去。

Stop The World

接下来说一点题外话,还记得刚开始说的Stop The World吗?由于GC的进行所以暂时让线程停下来。判别对象是否是垃圾的对象的算法是可达性算法,具体是怎么个算法就不在这里细说了。现在有个问题就是在STW(Stop The World)这段时间是遍历所有的对象进行标记吗?

当然不是了,如果是这样的话,那么在大型的服务器上一个GC岂不是要让程序停顿很长时间吗?在近些年推出的高级垃圾收集器中(CMS,G1)STW这段时间是用来给GC root引用的对象做标记的,只要每个根引用的对象被做了标记就结束STW,然后与各个线程并行的去遍历整个对象链。这样一来,可以节省很大一部分时间啊。

最后

Java虚拟机在垃圾方面在不同的内存带和不同的收集器上都有或多或少的不同。在Java团队对JDK的一次次更新中,我们这些使用者真的是获得了越来越好的体验了,谢谢他们的付出。如果大家想了解更详细的信息可以阅读《深入理解Java虚拟机》这本书,写的非常棒。本文只是笔者自己的理解和总结,如果有错误的地方还请大家指出。

Java垃圾回收的时间点相关推荐

  1. 假期三天,我肝了万字的Java垃圾回收,看完你还敢说不会?

    大家好,我是狂聊,上一篇已经把 Jvm 的运行区数据和类加载机制聊完了. 今天来说说 Java 垃圾回收,高频面试问题. 提纲附上,话不多说,直接干货 1.什么是垃圾回收? 垃圾回收(Garbage ...

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

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

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

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

  4. java垃圾回收机制串行_Java垃圾回收机制

    Java语言是一门自动内存管理的语言,不再需要的对象可以通过垃圾回收自动进行内存释放. Java运行时内存区域划分 JVM将Java程序运行时内存区域划分成以下几个部分: 程序计数器(Program ...

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

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

  6. java垃圾回收根对象_Java垃圾回收怎么理解?

    展开全部 Java的堆是一个运行时数据区,类的实例(对象)从中62616964757a686964616fe58685e5aeb931333339653664分配空间.Java虚拟机(JVM)的堆中储 ...

  7. Java垃圾回收(GC)、找垃圾的方式、GC Root、GC停顿、引用、垃圾收集算法、收集器、GC日志、安全点、安全区域

    1.垃圾回收 1.1概念 在Java语言中,垃圾回收(Garbage Collection,GC)是一个非常重要的概念. 它的主要作用是回收程序中不再被使用的内存,Java提供的GC功能可以自动监测对 ...

  8. Java垃圾回收(GC)机制详解

    Java垃圾回收(GC)机制详解 转自:https://www.cnblogs.com/xiaoxi/p/6486852.html 一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因 ...

  9. 53.垃圾回收算法的实现原理、启动Java垃圾回收、Java垃圾回收过程、垃圾回收中实例的终结、对象什么时候符合垃圾回收的条件、GC Scope 示例程序、GC OutOfMemoryError的示例

    53.垃圾回收算法的实现原理 53.1.目录 53.2.启动Java垃圾回收 53.3.Java垃圾回收过程 53.4.垃圾回收中实例的终结 53.5.对象什么时候符合垃圾回收的条件? 53.5.1. ...

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

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

最新文章

  1. centos防火墙端口配置
  2. 从零开始写一个迷你版的Tomcat
  3. ORB-SLAM3 Initializer.cpp函数解读
  4. 测试眉形的有哪个软件_心理测试:你的眉形是下面的哪种?测你生来命运如何!超准...
  5. 每日一皮:强大的sudo ...
  6. Delphi xe5 编译报environment.proj错误的解决
  7. python预处理标准化_tensorflow预处理:数据标准化的几种方法
  8. ambassador 学习七 Mapping说明
  9. 计算机网络-自顶向下方法(7th) 第二章 Review Questions 英文题目+中文答案
  10. 荐书丨被Dubbo虐过吗,反击开始!——《深入理解Apache Dubbo与实战》
  11. 4.创建并调用自动控制器(api)
  12. 树莓派搭建VSFTP记录---自用简记
  13. Python爬虫——selenium爬取当当畅销图书排行
  14. 编程软件有哪些比较好用
  15. 工业级三维扫描仪关于扫描前喷粉技巧,你了解多少?
  16. Excel怎么实现表格数据行间随机打乱排序
  17. matlab幻方置乱,幻方置乱,magic scrambling,音标,读音,翻译,英文例句,英语词典
  18. 一个学习C语言的好网站,推荐给大家
  19. 使用echarts生成海友网企业全国分布地图
  20. 智慧点餐系统多方面优化餐厅运作效率

热门文章

  1. 【SAP消息号F5053】
  2. 苹果sf字体_全网首发丨iOS13越狱系统字体分析+iOS13新字体分享
  3. 苹果怎么改字体_截图里的文字要改,字体怎么做到一模一样?
  4. WPS文档批量转换成PDF
  5. 微信公众号开发(个人订阅号版)
  6. 计算机桌面设置上时间表,怎么在电脑上安排每天的工作计划?你需要添加一款提醒功能强大的桌面便签软件...
  7. win10 悬浮日历_win10系统桌面上添加自带日历小工具的设置办法
  8. 台币转换计算机,Soulver 内建自动计算机功能的备忘录工具 货币换算、複杂数学式也支援...
  9. JQ实现图片预览(轮播,放大缩小,拖拽,ajax请求,旋转)
  10. 2021年计算机保研夏令营回忆(中科大、信工所、南开、天大)