上篇文章中,我们了解了Java虚拟机垃圾回收的思路和策略,这篇文章我们将了解Java是如何实现高效的回收算法的。

  我们需要了解,内存回收必须要保证“一致性”,意思就是在执行GC分析的时候,系统看起来要像是冻结在某一时间点上,不能出现在分析过程中,引用的情况还在发生变化,这样就无法进行分析,这是为什么在GC时必须要停顿所有的Java线程(官方称之为Stop The World),Java是通过引用计数器和可达性分析算法来判断一个对象是否可以被回收的,在进行可达性分析的时候,首先要枚举出所有的根结点GC-Roots,一个一个去挑选显然是不现实的,因为这会导致系统长时间的STW,而且,虚拟机是可以知道哪些地方存在存放着直接引用的,依靠使用一种叫做OOP的数据结构来达到这个目的,在类加载完成的时候,HotSpot就把对象内什么偏移量上是什么类型的数据计算出来,在JIT编译的过程中,也会在特定的位置几下栈和寄存器中哪些位置是引用,这样在GC扫描时,就可以直接获取这些信息了。

  上文也提到,并不会为每一条指令都创建OOP,因为这样会产生大量的内存消耗,得不偿失只会在特定位置创建,这个位置就是“安全点(Safe Point)”,程序只有在安全点才可以停下来执行GC,安全点设置的时候,为了追求合理(例如当需要执行GC时,不能让GC等候太久才进入安全点),这个标准就是“是否会让程序执行太久”,注意,这个判断条件不能以指令集的长度来判断,因为每条指令执行的时间都很短,其最明显的特征就是指令序列复用,例如方法跳转,循环跳转,异常跳转等,所以,具有这些功能的指令才会产生安全点。

  对于安全点,另一个需要考虑的问题是如何在GC发生时,让所有的线程都跑到最近的安全点上停下来,这里有两个方案选择:一是抢先式中断,就是在GC发生时,将所有的线程中断,如果发现有线程中断的地方不在安全点上,就恢复该线程,现在几乎没有虚拟机采用这种抢先式中断;而是主动式中断,设置一个标志,在GC发生时,该标志为真,在每个安全点上去查看这个标志,当这个标志为真时,就自己挂起中断。

  另外我们需要扩充一个安全域的概念,因为当有些线程正好处于Sleep或Block状态时,无法响应JVM的暂停请求,JVM也不可能等待CPU重新分配时间片,这就需要安全域来解决,安全域是指在一个代码片段中,引用关系不会发生变化,在这个区域中任何地方开始GC都是安全的,我们可以把安全域看作是对安全点的一个扩充。当线程执行到Safe Region时,就会标识自己已经进入SafeRegion,当需要执行GC时,不用管这种线程,当这种线程将要跳出SafeRegion时,会检查系统是否已经枚举完了根结点(或整个GC过程完成),如果没有,则必须等待到可以安全离开SafeRegion的信号为止。

  可以看出,JVM在具体的实现细节上遇到了很多问题,所以我们要深入了解JVM,学习优秀的解决方案,不能只停留在表面。

  本文我们了解了JVM在执行GC时的一些细节,下篇文章我们将会介绍几种流行的商用垃圾收集器。

深入理解JVM(六) -- GC执行原则和方案的更多相关文章

  1. 深入理解JVM+G1+GC.pdf (中文版带书签)

    目录 序 VII前言 IX 第1章 JVM & GC基础知识 11.1 引言 21.2 基本术语 31.2.1 Java相关术语 41.2.2 JVM/GC通用术语 241.2.3 G1涉及术 ...

  2. 深入理解JVM—字节码执行引擎

    原文地址:http://yhjhappy234.blog.163.com/blog/static/3163283220122204355694/ 前面我们不止一次的提到,Java是一种跨平台的语言,为 ...

  3. 深入理解JVM与GC回收

    JVM内存模型 java虚拟机在执行java程序的过程中会把它所管理的内存划分为不同的若干个不同的的数据区域,这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机的进程的启动而存在,有些区 ...

  4. 深入理解JVM(六)类文件结构

    6.1 关于类文件 1.class文件的一次编译,到处运行的跨平台性: 2.JVM不止有跨平台性,还有跨语言性,不管是JRuby还是Groovy写出来的程序,只要编译出符合JVM规范的class文件就 ...

  5. 深入理解JVM——虚拟机GC

    对象是否存活 Java的GC基于可达性分析算法(Python用引用计数法),通过可达性分析来判定对象是否存活.这个算法的基本思想是通过一系列"GC Roots"的对象作为起始点,从 ...

  6. Java 中级 学习笔记 1 JVM的理解以及新生代GC处理流程

    写在最前 从毕业到现在已经过去了差不多一年的时间,工作还算顺利,但总是离不开CRUD ,我觉得这样下去肯定是不行的,温水煮青蛙,势必有一天,会昏昏沉沉的迷失在温水里.所以,需要将之前学习JAVA 当中 ...

  7. 理解JVM GC

    理解JVM GC对于我们把控Java应用有很大的帮助.下面我从运维角度,把网上的JVM相关的资料整理如下,以加深对JVM GC的理解.如有错误的地方,请看官指正. JVM内存使用分类 JVM的内存分区 ...

  8. 深入理解JVM - 虚拟机字节码执行引 - 第八章

    概述从外观上看起来,所有的 Java 虚拟机的执行引擎都是一致的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果.主要从概念模型的角度来讲解虚拟机的方法调用和字节码执行. 运行时 ...

  9. jvm入门及理解(六)——垃圾回收与算法

    一.jvm垃圾回收要做的事情 哪些内存需要回收 什么时候回收 怎么回收 二.如何判断对象已经死亡,或者说确定为垃圾 引用计数法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器的值就加1: ...

随机推荐

  1. Multi-Agent Reinforcement Learning Based Frame Sampling for Effective Untrimmed Video Recognition

    Multi-Agent Reinforcement Learning Based Frame Sampling for Effective Untrimmed Video Recognition IC ...

  2. 解决vs2010按ctrl+f5,调试窗口一闪而过的方法

    vs2010调试按F5与按Ctrl+F5有什么区别 Ctrl F5测试运行后不自动推出控制台,直接按F5会自动退出去 解决vs2010按ctrl+f5,调试窗口一闪而过的方法 http://hi.ba ...

  3. linux学习(5):linux 性能瓶颈排查

    作为开发人员,肯定遇到过以下场景,应用突然卡住了,或者异常退出,cpu占用过高等各种异常情况,一般遇到这些异常情况,该如何去查找具体原因呢? linux和jdk提供了一些命令和工具来查看内存.cpu. ...

  4. 爬虫urllib2 的异常错误处理URLError和HTTPError

    urllib2 的异常错误处理 在我们用urlopen或opener.open方法发出一个请求时,如果urlopen或opener.open不能处理这个response,就产生错误. 这里主要说的是U ...

  5. 【Linux】walle 部署上线单报错:mv: cannot overwrite directory ‘/www’ with non-directory

    错误截图 问题分析:项目设置中. 目标集群部署路径错误, 举例: 假设你 项目名称:laofan 在目标服务器的路径: /www/wwwdata/laofan 那么你在标集群部署路径 就可以写: /w ...

  6. 开发日记:常用BAT批处理

    备份文件:BackupSourceCode.bat ::自动备份当前文件夹 ::by luomg, 21:15 2010-10-13 ::minguiluo@163.com @echo off tit ...

  7. 【python基础】python开启GPU加速

    前言 训练时使用GPU可以加速程序运行,本文介绍如何使用GPU加速. 前提条件 1. 机子有GPU显卡,并安装GPU显卡驱动: 2. 安装GPU的使用环境,CUDA等: 3. 打开nvidia-smi ...

  8. [LeetCode] 49. Group Anagrams 分组变位词

    Given an array of strings, group anagrams together. For example, given: ["eat", "tea& ...

  9. [LeetCode] 280. Wiggle Sort 摆动排序

    Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...

  10. python gzip

    通常用gzip压缩过的云端数据需要做解压处理,以下代码主要用python3实现对获取到的云端gzip压缩数据进行还原. # -*- coding: utf-8 -*- ""&quo ...