深入理解Java虚拟机2-chap3-斗之气9段
一、GC需要完成三件事
- 哪些内存需要回收:找出不需要使用的对象
- 什么时候回收:JVM空闲/堆内存紧张
- 如何回收:回收垃圾的策略
二、寻找已死对象:第一件事
判断对象是否存活算法
1.引用计数算法
- 原理:给对象添加一个引用计数器,每当有一个地方引用本对象,计数器值加1,无法解决对象之间循环引用问题
- 代码:对象A中引用指向B,B反之,当引用置为null后,堆中的对象仍然在互相引用着
package com.chengjie.C3;
class ReferenceCountGC {
public Object instance = null;
private static final int _1MB = 1024 * 1024;
private byte[] bigSize = new byte[2 * _1MB];
public static void testGC() {
ReferenceCountGC objA = new ReferenceCountGC();
ReferenceCountGC objB = new ReferenceCountGC();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
System.gc();
}
}
public class T3_1 {
public static void main(String[] args) {
ReferenceCountGC.testGC();
}
}
2.可达性分析算法(主流方法)
- 原理:通过一系列称为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明对象不可用
- 可作为GC Roots的对象包括:
①虚拟机栈中引用的对象;
②方法区中类静态变量引用的对象;
③方法区中常量引用的对象;
④本地方法栈JNI(即一般的Native方法)引用的对象。

引用分类
1.强引用
2.软引用
3.弱引用
4.虚引用
对象真正生死时刻
即使在可达性分析中不可达的对象,也并非非死不可,只是缓刑,真正宣告一个对象死亡,需要经历两次标记过程
1.对象在可达性分析中不可达,判断其是否有必要执行finalize()方法?
①有必要:选出来进入F-Queue
②无必要:等待回收
2.在低优先级线程上执行finalize()方法,看其是否重新建立与GC Roots中的对象建立关联?
①建立:逃脱回收
②未建立:等待回收

注:对象的finalize()方法只会被系统调用一次,即只能自我拯救一次
三、垃圾回收算法
1.标记-清除算法
- 原理:标记处所有需要回收的对象,标记完后统一回收所有被标记的对象


- 优点:
- 缺点:
①效率:标记、清扫效率低
②空间:会产生大量内存碎片,当分配一个对象由于连续内存不足,会触发对于的GC
2.复制算法
- 原理:将内存空间分为两块,一块内存用完则将存活对象复制到另一块,然后把前一块内存清理掉

- 优点:
①无内存碎片问题
②实现简单,分配效率高,只需要移动指针即可
- 缺点:
①浪费了一半内存
3.标记-整理算法
- 原理:标记完对象后,非直接将可回收对象清理,而是将存活对象向一段移动,然后清理掉边界外的内存

- 优点:
①无内存碎片问题
- 缺点:
①标记过程效率低
4.分代收集算法
- 原理:根据对象存活周期的不同将内存分为几块,一般为新生代与老年代
①新生代:新生代每次垃圾回收有大量对象死去,故采用复制算法
②老年代:对象存活率高,使用标记-清除或者标记-整理算法
- 优点:分代回收,资源利用率高,效率高
四、HotSpot算法实现细节
1.枚举根节点
- GC进行可达性分析时,必须STW,即使是CMS收集器
- 当系统STW,JVM不需要挨个检查所有上下文和引用,通过OopMap数据结构可以直接知道哪些地方存放对象引用
- OopMap:类加载完成时,HotSpot把对象内什么偏移量上是什么类型的数据计算出来
2.安全点
- 并非为任何指令都生成OopMap,而是在能确保具有让程序长时间执行的特征的那些点
- GC发生时,如何让所有线程运行到安全点停顿下来
①抢先式中断
②主动式中断
3.安全区域
- 有些内存未分配cpu,无法响应JVM的中断请求,JVM不可能等待其执行并进入安全点
- 解决方案:设置安全区域,此区域引用关系不发生变化
五、垃圾收集器

新生代垃圾收集器
1.Serial:单线程

2.ParNew:多线程

3.Parallel Scavenge:ParNew的升级版,更关注吞吐率

老生代垃圾收集器
1.CMS:获取最短回收停顿时间
- 优点:
①耗时很长的并发标记与并发清楚过程都未STW
- 缺点:
①吞吐量低
②无法处理浮动垃圾
③基于标记-清除,会产生内存碎片,可能提前触发Full GC

2.Serial Old(MSC)

3.Parallel Old
同新生代的Parallel Scavenge
G1垃圾收集器
- 优点:
①并行
②多线程
③垃圾回收率高
④分代收集:新生代(复制) 老生代(标记-整理)
⑤不会产生内存碎片
- 工作流程
①初始标记
②并发标记
③最终标记
④筛选回收:可预测停顿,根据设置阈值,选择回收哪些

六、内存分配与回收策略
对象主要分配在新生代的Eden区,若启动了本地线程分配缓冲,将按线程优先在TLAB上分配,少数情况下可能直接分配在老年代
分配原则
1.对象优先在Eden分配
2.大对象直接进入老年代:避免在Eden与Survivor区之间发生频繁拷贝
3.长期存活对象将进入老年代:熬过一次Minor GC,年龄长1
4.对象年龄判断:Survivor区相同年龄对象总和达到区空间的一半,年龄大于等于的对象可以进入老年代
5.空间分配担保:
①Minor GC发生前,JVM会检查老年代可用最大连续空间是否大于新生代对象总和,如成立,则安全;
②若不成立,看是否设置了允许担保失败值,若允许,检查老年代可用最大连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,则尝试一次Minor GC,这是有风险的;
如果小于,或者未设置允许担保失败,则进行一次Full GC
参考:
https://www.jianshu.com/p/0269237a229d
https://gavinzhang1.gitbooks.io/java-jvm-us/content/la_ji_shou_ji_qi_yu_nei_cun_fen_pei_ce_lve.html
深入理解Java虚拟机2-chap3-斗之气9段的更多相关文章
- 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具
上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...
- 《深入理解 java虚拟机》学习笔记
java内存区域详解 以下内容参考自<深入理解 java虚拟机 JVM高级特性与最佳实践>,其中图片大多取自网络与本书,以供学习和参考.
- (1) 深入理解Java虚拟机到底是什么?
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机 作为一个Java程序员,我们每天都在写Java ...
- 深入理解java虚拟机(7)---线程安全 & 锁优化
关于线程安全的话题,足可以使用一本书来讲解这些东西.<Java Concurrency in Practice> 就是讲解这些的,在这里 主要还是分析JVM中关于线程安全这块的内容. 1. ...
- 深入理解java虚拟机(6)---内存模型与线程 & Volatile
其实关于线程的使用,之前已经写过博客讲解过这部分的内容: http://www.cnblogs.com/deman/category/621531.html JVM里面关于多线程的部分,主要是多线程是 ...
- 深入理解java虚拟机(5)---字节码执行引擎
字节码是什么东西? 以下是百度的解释: 字节码(Byte-code)是一种包含执行程序.由一序列 op 代码/数据对组成的二进制文件.字节码是一种中间码,它比机器码更抽象. 它经常被看作是包含一个执行 ...
- 深入理解java虚拟机(4)---类加载机制
类加载的过程包括: 加载class到内存,数据校验,转换和解析,初始化,使用using和卸载unloading过程. 除了解析阶段,其他过程的顺序是固定的.解析可以放在初始化之后,目的就是为了支持动态 ...
- 深入理解java虚拟机(1)------内存区域与内存溢出
在C++领域,关于C++的内存存储,结构等等,有一本书:深度探索C++对象模型,讲解的非常透彻. 而Java确把这一工作交给了虚拟机来处理. 我们首先来看看关于内存的问题. 1.问题: 1)java ...
- 什么是HotSpot VM & 深入理解Java虚拟机
参考 http://book.2cto.com/201306/25434.html 另外,这篇文章也是从一个系列中得出的: <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)> ...
- 【Todo】深入理解Java虚拟机 读书笔记
有一个在线系列地址 <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)> http://book.2cto.com/201306/25426.html 已经下载了这本书(60多M ...
随机推荐
- 从 Firefox 35 版本开始,就无法兼容 PAC 式代理
经过反复的测试,包括在“高级”选项里启用 PAC 代理的设置,也都无法使用 PAC 的代理——无法登陆 Twitter 账号,无法打开 Google 网页. 不知道各位有什么好办法吗? 以及中文火狐社 ...
- mysql索引及sql执行顺序
1, 红黑树 同一层级的黑树到根结点经历的黑树数目一样 最坏情况的时间复杂度 lg n 是二叉树b树 结点可以有多个孩子 b+树 父节点不存储数据聚集索引)的叶子节点会存储数据行,也就是说数据和索引是 ...
- [No0000130]WPF 4.5使用标记扩展订阅事件
自从我上次写到关于标记扩展的时候已经有一段时间了...... Visual Studio 11 Developer Preview的发布给WPF带来了一些新功能,让我有理由再次使用它们.我要在这里讨论 ...
- 基于Docker搭建MySQL主从复制
摘要: 本篇博文相对简单,因为是初次使用Docker,MySQL的主从复制之前也在Centos环境下搭建过,但是也忘的也差不多了,因此本次尝试在Docker中搭建. 本篇博文相对简单,因为是初次使用D ...
- 免费SSL证书Let's Encrypt(certbot)安装使用教程
免费SSL证书Let's Encrypt(certbot)安装使用教程 https://www.vpser.net/build/letsencrypt-certbot.html
- [daily][gnucash] 复式记账
管理, 是成就人生的第一步. 管钱,是第一步中的第一小步. 选了又选,终于选了一个软件,gnucash, 但是, 他有点专业, 用之前需要搞懂一下会计概念. 即: 复式记账 gnucash手册的这一章 ...
- [knowledge][perl][pcre][sed] sed / PCRE 语法/正则表达式
一直用sed一直没有正经的学过语法,一直一知半解的用着. 因为,它用来perl的语法,要想搞懂,首先要搞懂perl,系统的入个门... 之前,man sed,man了好多次,总是没找到关键内容,今天在 ...
- [yum] yum使用光盘安装或更新软件
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_ ...
- 斜率优化&单调性优化的相似性
写了一道单调性优化发现 跟斜率优化很像,而且这道题目感觉质量非常的好. 其实斜率优化是基于单调性优化的,但是面对这道题 我竟然连单调性优化都不太会,尽管这个模型非常不好理解. 对于每道题 我都会打一个 ...
- 图->存储结构->十字链表
文字描述 十字链表是有向图的另一种链式存储结构. 在十字链表中,对应于有向图中每一条弧有一个结点,对应于每个顶点也有一个结点.这些结点的结构如下所示: 在弧结点中有5个域: 尾域tailvex和头域h ...