深入理解JVM(六) -- GC执行原则和方案
上篇文章中,我们了解了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执行原则和方案的更多相关文章
- 深入理解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涉及术 ...
- 深入理解JVM—字节码执行引擎
原文地址:http://yhjhappy234.blog.163.com/blog/static/3163283220122204355694/ 前面我们不止一次的提到,Java是一种跨平台的语言,为 ...
- 深入理解JVM与GC回收
JVM内存模型 java虚拟机在执行java程序的过程中会把它所管理的内存划分为不同的若干个不同的的数据区域,这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机的进程的启动而存在,有些区 ...
- 深入理解JVM(六)类文件结构
6.1 关于类文件 1.class文件的一次编译,到处运行的跨平台性: 2.JVM不止有跨平台性,还有跨语言性,不管是JRuby还是Groovy写出来的程序,只要编译出符合JVM规范的class文件就 ...
- 深入理解JVM——虚拟机GC
对象是否存活 Java的GC基于可达性分析算法(Python用引用计数法),通过可达性分析来判定对象是否存活.这个算法的基本思想是通过一系列"GC Roots"的对象作为起始点,从 ...
- Java 中级 学习笔记 1 JVM的理解以及新生代GC处理流程
写在最前 从毕业到现在已经过去了差不多一年的时间,工作还算顺利,但总是离不开CRUD ,我觉得这样下去肯定是不行的,温水煮青蛙,势必有一天,会昏昏沉沉的迷失在温水里.所以,需要将之前学习JAVA 当中 ...
- 理解JVM GC
理解JVM GC对于我们把控Java应用有很大的帮助.下面我从运维角度,把网上的JVM相关的资料整理如下,以加深对JVM GC的理解.如有错误的地方,请看官指正. JVM内存使用分类 JVM的内存分区 ...
- 深入理解JVM - 虚拟机字节码执行引 - 第八章
概述从外观上看起来,所有的 Java 虚拟机的执行引擎都是一致的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果.主要从概念模型的角度来讲解虚拟机的方法调用和字节码执行. 运行时 ...
- jvm入门及理解(六)——垃圾回收与算法
一.jvm垃圾回收要做的事情 哪些内存需要回收 什么时候回收 怎么回收 二.如何判断对象已经死亡,或者说确定为垃圾 引用计数法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器的值就加1: ...
随机推荐
- GO语言GIN框架入门
Gin框架介绍 Gin是一个用Go语言编写的web框架.它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍. 中文文档 Gin框架安装与使用 ...
- 【软工实践】Beta冲刺(3/5)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 新增数据分析展示等功能API 服务器后端部署,API接口的beta版实现 展示 ...
- hdu5387 钟表指针之间夹角(分数计算,模拟)
题意: 给你一个24格式的数字时间,(字符串),问你这个时刻时针与分针 时针与秒针 分针与秒针 之间的夹角, 我们发现 秒针每秒转6度,分针每秒转1/10度,每分转6度,时针每小时转30度,每分转1/ ...
- Netty 多客户端连接与通信
实现场景: 聊天 服务端,客户端A,客户端B,客户端C.当客户端发送消息给服务端后,服务端在将这条消息广播个所有客户端户端A,客户端B,客户端C. 需求1: 客户端上线后,会通知所有客户端上线. 如客 ...
- Python将print输出内容保存到指定文件中
#!/usr/bin/python # -*- coding: utf- -*- import sys import os class Logger(object): def __init__(sel ...
- MySQL索引知识点及面试常问题
索引的功能 索引可以大幅增加数据库的查询的性能,在实际业务场景中,或多或少都会使用到. 但是索引是有如下 2 个代价的: 需要额外的磁盘空间来保存索引 对于插入.更新.删除等操作由于更新索引会增加额外 ...
- rqalpha学习-2
conf = default_config()deep_update(user_config(), conf)deep_update(project_config(), conf) 三种不同级别的 ...
- 解决python写入mysql中datetime类型遇到的问题
解决python写入mysql中datetime类型遇到的问题 刚开始使用python,还不太熟练,遇到一个datetime数据类型的问题: 在mysql数据库中,有一个datetime类型的字段用于 ...
- Excel四象限散点图的制作方法
Excel中四象限散点图带文本数据标签,可以在散点图的基础上进行一些设置即可得到,无需第三方插件或者宏代码,非常方便,以office2013为例,效果如下: 步骤: 1.准备好数据源,选中两列数据源( ...
- rpm和deb包制作和升级执行步骤
deb安装包升级和安装都是dpkg -i .deb命令,升级时直接覆盖安装新包安装步骤:1 preinst install2 postinst configure升级步骤:1 先执行旧包prerm u ...