深入理解java虚拟机-第三章
1、概述
2、对象已死吗?
引用计数器
给对象添加一个引用计数器,每当有引用时,计数器加1,引用失效时,计数器减1;任何时刻计数器为0的对象就是不可能再被使用的。
若对象是循环引用,则无法处理。JVM不使用。
可达性分析算法
通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所经过的路径称为引用链(Reference Chain),当一个对象没有任何引用链相连时,表明该对象不可用。
Java语言中,可作为 GC Roots的对象包括如下:
虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI(即一般说的Native方法)引用的对象。
Java中的引用:
强引用(Strong Reference) 类似“Object obj=new Object()”,这类的引用,只要强引用还存在,对象永远不会被回收。
软引用(Soft Reference)用来描述一些还有用但并非必需的对象。在系统将要发生内存溢出前,会对这类对象进行回收;如果这次回收还没有足够的内存,才会抛出内存溢出异常。SoftReference类来实现。
弱引用(Weak Reference) 非必需的对象,但强度比软引用更弱一点。当垃圾收集器工作时,无论内存是否够用,都会回收这类引用。WeakReference来实现。
虚引用(Phantom Reference)幽灵引用或幻影引用,最弱的一种引用关系,完全不对其生存时间构成影响,也无法通过虚引用来取得一个对象实例,唯一目的就是能在这个对象被收集器回收时收到一个系统通知,用PhantomReference来实现
3、垃圾收集算法
标记清除算法 Mark-Sweep
首先标记出所要回收的对象,在标记完成后统一回收所有被标记的对象。可能会造成碎片。
复制算法Copying
将可用内存按容量划分为大小相等的两块,每次中使用其中的一块,当这一块用完了,将存活的对象复制到另一块中,然后把已使用的一块清空。
每次对整个半区进行内存回收,也不用考虑内存d碎片;代价为只使用了内存的一半。
现在商业虚拟机都使用这种算法来回收 新生代,不过将内存分为较大的Eden和两块较小的Survior,每次只使用Eden和一块Survior,回收时一次复制到另一块Survivor,默认比例8:1:1.
标记-整理算法
与 标记-清除算法一样,但是后续步骤是让所有存活的对象都向一端移动,最后直接清理掉端边界以外的内存。
分代收集算法 Generation Collection
根据对象存活周期的不同将内存划分为几块
默认的,新生代与老年代的比例值为1:2(可以通过参数-XX:NewRatio来指定
Eden:from:to=8:1:1可以通过--XX:SurvivorRatio来指定
4、HotSpot的算法实现
枚举根结点
从可达性分析中从GC Root节点找引用链的操作中,需要停顿所有Java执行线程(Stop The World, STW)。HotSpot的实现中使用一组称为OopMap的数据结构来实现,当执行系统停顿下来后,并不需要一个不漏的检查所有执行上下文和全局的引用位置。
安全点
安全区域
5、垃圾收集器
Serial收集器
单线程的收集器,必需暂停其他所有的工作线程,简单而高效。
ParNew
Serial的多线程版本,暂停其它工作线程,启用多个回收线程来回收。
Parallel Scavenge收集器
目标是达到一个可控制的吞吐量,吞吐量就是Cpu运行用户代码的时间和CPU总消耗时间的比值。
Serial Old收集器
Serial收集器的老年代版本。
Parallel Old收集器
老年代的Parallel Scavenge收集器,使用多线程和“标记-整理”算法。
CMS收集器 Concurrent Mark Sweep
以获取最短回收停顿时间为目标的收集器
初始标记 (CMS initial mark), Stop the World,只是标记一下GC Roots能直接关联到的对象,速度很快
并发标记(CMS concurrent mark),进行GC Roots Tracing的过程。
重新标记(CMS remark), Stop the World, 为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录
并发清除(CMS concurrent sweep)
G1收集器 Garbage-first
面向服务端应用的垃圾收集器
1、并发与关行。 充用利用多CPU、多核环境下的硬件优势,来缩短Stop-The-World从停顿的时间,可以通过并发的文萃上java程序继续执行
2、分代收集。 分不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象
3、空间整合。从整体来看是基于“标记-整理”算法的收集器,从局部上来看是基于“复制”算法实现的, 运行期间不会产生内存碎片,收集后能提供规整的可用内存。
4、可预测的停顿
Young Generation: Serial、ParNew、Parallel Scavenge、G1
Tenured(old) Generation:CMS、Serial Old、Parallel Old
6、内存分配和回收策略
对象优先在Eden分配,当Eden区没有足够空间分分配时,触发一次GC
大对象直接进入老年代
长期存活的对象进行老年代
虚拟机给每个对象定义了一个对象年龄计数器,如果对象在Eden出生并经过第一次MinorGC后仍然存活,并且能被Survior容纳的话,将被移动到Survivor空间中,并且对象年龄为1.
对象在Survivor中每一次Minor GC,年龄增加1,当年龄增加到一定程序,就晋升老年代
动态对象年龄判定
为了更好地适应不同程序的内存状态,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivorp空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代
空间分配担保
深入理解java虚拟机-第三章的更多相关文章
- 深入理解Java虚拟机 第三章 垃圾收集器 笔记
1.1 垃圾收集器 垃圾收集器是内存回收的具体实现.以下讨论的收集器是基于JDK1.7Update14之后的HotSpot虚拟机.这个虚拟机包含的所有收集器有: 上图展示了7种作用于不同分代的收集 ...
- [Note][深入理解Java虚拟机] 第三章 垃圾收集器与内存分配策略笔记
书上关于GCTimeRatio的讲解有点难以理解,查看Oracle的文档后重新理解了下 -XX:GCTimeRatio 运行时间 / GC时间 当GCTimeRatio为19时,运行时间是GC时间的1 ...
- 深入理解Java虚拟机第三版,总结笔记【随时更新】
最近一直在看<深入理解Java虚拟机>第三版,无意中发现了第三版是最近才发行的,听说讲解的JDK版本升级,新增了近50%的内容. 这种神书,看懂了,看进去了,真的看的很快,并没有想象中的晦 ...
- 深入理解java虚拟机-第13章-线程安全与锁优化
第十三章 线程安全与锁优化 线程安全 java语言中的线程安全 1 不可变.Immutable 的对象一定是线程安全的 2 绝对线程安全 一个类要达到不管运行时环境如何,调用者都不需要额外的同步措施, ...
- 深入理解Java虚拟机-第1章-走进Java-读书笔记
第 1 章 走近 Java 前言 Java 的技术体系主要是由支撑 Java 程序运行的虚拟机.为各开发领域提供接口支持的 Java API.Java 编程语言及许许多多的第三方 Java 框架(如 ...
- 《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常
第二章 Java内存区域与内存溢出异常 2.2 运行时数据区域
- 深入理解java虚拟机-第六章
第6章 类文件 6.3 Class类文件的结构 Class文件是一组以8位字节为基础单位的二进制流. Class文件格式采用一种类似C语言结构伪结构存储数据,这种伪结构中只有两种数据类型:无符号数和表 ...
- 深入理解java虚拟机(三)对象回收判断算法以及死亡过程
在堆里面存放着Java几乎所有的对象实例,垃圾收集器要进行垃圾回收,要做的第一步便是找出那些对象是需要回收的. 怎么判断对象是否需要回收? 常用的方法有两种. 1.引用计数算法.为每一个对象添加一个引 ...
- 深入理解java虚拟机_第二章_读书笔记
1.本章内容目录: 概述 运行时数据区域 程序计数器 java虚拟机栈 本地方法栈 java堆 方法区 运行时常量池 直接内存 HotSpot虚拟机对象探秘 对象的创建 对象的内存布局 对象的访问定位 ...
随机推荐
- LeetCode 1. Two Sum 找到两数字求和索引集合
https://leetcode.com/problems/two-sum/description/ 第一种方法 遍历查找 // // main.m // HFCDemo // // Created ...
- iOS导入高德地图出现缺失armv7--"Undefined symbols for architecture armv7"
在已有项目中使用pod导入高德地图,报了以下错误: ld: warning: directory not found for option '-L/Users/paul/iOS/yun-hui-yi/ ...
- Web层辅助工具类
Java web开发中经常用到的一些方法: import java.io.BufferedReader; import java.net.InetAddress; import java.net.Un ...
- Linux下代理服务器(proxy)配置
Linux下有很多程序都只有命令行接口,对于这类程序,它们通过代理服务器(proxy)访问网络的方式也不尽相同.在本文中Easwy总结了一些常用Linux程序配置代理服务器的方法. [ 通用代理服务器 ...
- 项目中使用better-scroll实现移动端滚动,报错:Cannot read property 'children' of undefined better-scroll
就是外面的盒子和要滚动的元素之间要有一层div, 插件挂载的元素是menuWrapper,可以滚动的元素是ul,在这两个元素之间加一个div元素即可解决问题.
- CSS气泡提示框 可自定义配置箭头
在线演示 本地下载
- github Git-fork-别人的项目后更新代码的方法
用github还处于菜的阶段,遇到问题简单记录. 举个例子,需要 fork 这个项目 https://github.com/tarobjtu/WebFundamentals.git 点击 for ...
- SQL-ALTER-change和modify区别
ALTER 对于列的应用: 1.更改列名 格式:CHANGE old_col_name new_col_name column_definition 保留old和new列名 ...
- (+4)2.2UML建模图
①用例图 [用途]:帮助开发团队以一种可视化的方式理解系统的功能需求. 用例图所包含的元素如下: 1. 参与者(Actor) 表示与您的应用程序或系统进行交互的用户.组织或外部系统.用一个小人表示. ...
- Mac下编译tesseract报错 DotProductAVX can't be used on Android
因为我的mac是64位的,所以用32位编译,执行的时候肯定会出错的. 所以应该在 arch/simddetect.cpp中把这句# define X86_BUILD 1 注释掉,就可以了. 参考 ht ...