[深入理解JVM虚拟机]第3章-垃圾收集器、内存分配策略
垃圾收集器
判断对象是否需存活
- 回收堆
- 判断对象是否存活:
- 方法一:引用计数法。对象被引用一次就+1,当为0时回收对象。缺点:无法解决循环引用问题。
- 方法二:可达性分析算法。记录当前对象是否有和GC Roots中对象的引用链。(其中,可以作为GCRoots对象的有:虚拟机栈中引用的对象、方法去中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中引用的对象。)
- 不可达对象并不是一定被垃圾收集的,当这个对象有必要执行finalize()并finalize里自己和某个对象建立关联,即可在第二次标记时被移出“即将回收”的集合。但强烈建议不在finalize()里来拯救对象,使用try-finally等其他方式或许更好。
- 引用分为:强引用(new出来的)、软引用(SoftReference类实现)、弱引用(WeakReference类实现)、虚引用(PhantomReference类实现)。是为了描述一类对象:内存空间还够的时候能保存在内存,不够就可以抛弃这些对象。
- 判断对象是否存活:
- 回收方法区
- 主要是回收方法区中的废弃常量和无用的类。
- 废弃常量:假如在常量池中存在字符串 "abc",如果当前没有任何 String 对象引用该字符串常量,就说明常量 "abc" 就是废弃常量
- 无用的类必须满足三点:Java堆中不存在该类实例;加载该类的ClassLoader已经被回收;该类对应的java.lang.Class对象没有在其他地方被引用。
- 无用的类不一定要被回收,可以通过参数与进行控制。
- 主要是回收方法区中的废弃常量和无用的类。
垃圾收集算法(内存回收方法论)
- 分代收集算法:把堆对象分为新生代(存活率低的对象)和老年代(存活率高的对象)。
- 老年代:
- 方法一:标记-清除算法:把要回收的对象标记一下,然后清除。缺点:标记和清除两个操作效率低、会造成空间碎片可能导致二次回收。
- 方法二:标记- 整理算法:把要回收的对象标记一下,然后留下的对象连续排。
- 新生代:复制算法:
- 把堆内存分为两部分,只使用其中的一部分装对象,当装不进去后,把留存对象拷贝到另一部分,连续放置。
- 两部分比例可以超过1:1比如9:1,但要使用内存担保,用老年代的内存空间担保,即1放不下时候放老年代去。所以只适合新生代使用。
- 老年代:
HotSpot的算法实现(HotSpot如何发起内存回收)
- 关于枚举根节点:
- HotSpot中,使用OopMap数据结构使虚拟机直接指导哪些地方存着对象引用,这样GC扫描时可以直接得知这些信息。
- 具体地,类加载完成后,HotSpot就把对象内什么偏移量是什么数据类型算出来。JIT编译过程中,也会记录下栈和寄存器中哪些位置是引用。
- 安全点:
- 因为对象引用是变化的,所以OopMap是变化的,但不可能每一时刻都记录对应的OopMap,故只有在安全点才记录了OopMap,GC只有在安全点才回发生,使线程暂停。
- 如何让所有线程跑到安全点才停下来?主流采用主动式中断,在安全点设置标志,各个线程主动去轮询到没到标志,到了的话就停下。
- 安全区域:
- 当程序不执行的时候,即没有分配CPU时间的时候,无法响应JVM的中断请求走到安全点挂起,这就需要安全区域。
- 安全区域是指在一段代码片段中,引用关系不发生变化。
- 当线程执行到安全区域,就标识进入安全区域,此时JVM发起GC就不用管这个线程了,当线程要离开安全区域时,检查是否已完成了GC,完成即可离开安全区域。
垃圾收集器(内存回收的具体实现、特点)
重点1:CMS(Concurrent Mark Sweep)收集器:老年代收集器
- 并发的收集器
- 以减少用户线程的停顿,加快响应速度为目标
- 基于标记-清除算法
- 步骤
- 1 初始标记:标记和GC Roots直接关联的对象(stop worlds)。
- 2 并发标记:垃圾回收线程和用户线程并发,进行可达性分析,标记所有和GC Roots相连的节点。
- 3 重新标记:由于上一步可能会有标记更改,对这些更改进行重新标记(stop worlds)。
- 4 标记清除:垃圾回收线程和用户线程并发,进行标记请清除
- 缺点
- 1 对CPU资源敏感。因为占用了一部分线程,所以虽然减少停顿,但会导致应用程序变慢,尤其是CPU资源少的时候。
- 2 无法处理浮动垃圾。由于4标记清除是并发进行的,这一过程用户线程新产生的垃圾本次无法处理,并且要预留一部分内存空间给此时产生的垃圾,如果预留的不够,就会造成本次垃圾收集失败,导致再次GC。
- 3 由于使用标记-清除算法,所以会产生内存碎片。
重点2:G1 (Garbage-First) 收集器:自己可以负责全部的GC收集
- G1是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器,以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征。
- 特点
- 可以不与其他垃圾收集器配合独自管理GC,但是在内部仍保留分代概念。
- 整体基于标记-整理算法,局部基于复制算法。
- 可预测的停顿时间:建立可预测的停顿时间模型,能让使用者明确指定stop worlds在一个长度为 M 毫秒的时间片段内。 内部实现:使用 Region 划分内存空间,G1 收集器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region。保证了 GF 收集器在有限时间内可以尽可能高的收集效率(把内存化整为零)。
- 并行与并发:可利用多颗cpu、多核优势,减少stop worlds 时间。并且支持并发。
- 步骤
- 初始标记
- 并发标记
- 最终标记
- 筛选回收
Serial收集器(新生代、单线程、复制算法、Client模式)、ParNew收集器(新生代、多线程、复制算法、Server模式)、Serial Old收集器(老年代、单线程、标记整理算法、Client模式)、CMS
这其中的新生代可以与老年代搭配使用。
Parallel Scavenge收集器(新生代、多线程、重吞吐、有自适应调节策略、复制算法) 、Parallel Old收集器(老年代、多线程、标记整理算法)
两者可搭配使用。
重吞吐是指应用程序总体完成时间短,但停顿可能大一些,适合后台、用户交互少的应用。
理解GC日志
GC日志包含:发生时间、停顿类型(GC/Full GC)、DefNew等表示GC发生的区域时新生代/老年代/永久代、GC前后内存总容量变化、堆内存容量变化。
Minor GC 与 Major GC
- 新生代 GC(Minor GC):指发生新生代的的垃圾收集动作,Minor GC 非常频繁,回收速度一般也比较快。
- 老年代 GC(Major GC/Full GC):指发生在老年代的 GC,出现了 Major GC 经常会伴随至少一次的 Minor GC(并非绝对),Major GC 的速度一般会比 Minor GC 的慢 10 倍以上。
内存分配
todo
参考连接
https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/jvm/JVM垃圾回收.md#46-cms-收集器
[深入理解JVM虚拟机]第3章-垃圾收集器、内存分配策略的更多相关文章
- 《深入理解java虚拟机》读书笔记——垃圾收集与内存分配策略
可回收判定两种算法 引用计数法(Reference Counting):引用为0时可回收. 可达性分析法(Reachability Analysis): 从GCRoots对象到这个对象不可达. GCR ...
- 深入理解Java虚拟机 第三章 垃圾收集器 笔记
1.1 垃圾收集器 垃圾收集器是内存回收的具体实现.以下讨论的收集器是基于JDK1.7Update14之后的HotSpot虚拟机.这个虚拟机包含的所有收集器有: 上图展示了7种作用于不同分代的收集 ...
- [Note][深入理解Java虚拟机] 第三章 垃圾收集器与内存分配策略笔记
书上关于GCTimeRatio的讲解有点难以理解,查看Oracle的文档后重新理解了下 -XX:GCTimeRatio 运行时间 / GC时间 当GCTimeRatio为19时,运行时间是GC时间的1 ...
- 深入理解java虚拟机(2)------垃圾收集器和内存分配策略
GC可谓是java相较于C++语言,最大的不同点之一. 1.GC回收什么? 上一篇讲了内存的分布. 其中程序计数器栈,虚拟机栈,本地方法栈 3个区域随着线程而生,随着线程而死.这些栈的内存,可以理解为 ...
- 深入理解JVM(5)——垃圾收集和内存分配策略
1.垃圾收集对象 垃圾收集主要是针对堆和方法区进行. 程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收. 哪 ...
- 深入理解JVM(5)——HotSpot垃圾收集器详解
HotSpot虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器.根据新生代和老年代各自的特点,我们应该分别为它们选择不同的收集器,以提升垃圾回收效率. ...
- JVM基础学习(二):内存分配策略与垃圾收集技术
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来 垃圾收集概述 Java内存模型中的堆和方法区是垃圾收集技术所需要关注的终点,因为其他的区域会跟 ...
- [深入理解JVM虚拟机]第2章-Java内存区域与内存溢出异常
2.0引-Java内存区域中,栈内存和堆内存分别装什么,为什么? 栈:解决程序的运行问题,即程序如何执行,或者说如何处理数据. 堆:解决的是数据存储的问题,即数据怎么放,放在哪儿. 参考链接https ...
- <<深入Java虚拟机>>-第三章-垃圾收集器与内存分配策略-学习笔记
垃圾收集 垃圾收集(Garbage Collection,GC),垃圾收集需要完成的三件事情. 哪些对象需要回收 什么时候回收 如何回收 如何确定对象已死(即不可能在被任何途径引用的对象) 引用计数算 ...
随机推荐
- 在K3s上使用Kong网关插件,开启K3s的无限可能!
我的工作中很重要的一部分是参加各种各样的技术会议.最近参加的是去年11月的北美KubeCon,在会议的最后一天,所有人都焦头烂额,我也一直机械地向不同的人重复我的自我介绍.后来,我已经十分烦躁,决定逃 ...
- 《MySQL必知必会》简介、使用
2.MySQL简介 2.1 什么是MySQL 我们在前一-章中介绍了数据库和SQL.正如所述,数据的所有存储. 检索.管理和处理实际上是由数据库软件一 DBMS (数据库管理系统) 完成的. MySQ ...
- 浏览器自动化的一些体会9 webBrowser控件之零碎问题3
WebBrowser控件最大的优点是可以轻松嵌入win form程序中,但是微软好像对这个控件没什么兴趣,这么多年了还没有改进,结果造成一堆问题. 1. 不支持https 2. 缺省模拟ie 7,如果 ...
- Fiddler+模拟器+APP抓包HTTPS 为什么有时候抓不到?
抓包的原理是什么? 代理 客户端请求 -> 经过代理 -> 到达服务端 服务端返回 -> 经过代理 -> 到达客户端 任何Https的App都能抓到包么? Android7.0 ...
- PAT 2-05. 求集合数据的均方差(15)
题目意思:求N个给定整数的均方差. 求平均值需要先转化为double类型,如果没转化会损失精度,造成错误. 代码如下: #include<iostream> #include<cma ...
- 仿京东BOE官网 JavaScript代码
let items = document.getElementsByClassName('item'); let points = document.getElementsByClassName('p ...
- 第1篇 Scrum 冲刺博客
每个成员在Alpha阶段认领的任务 钟智锋 内容 工时 客户端请求对局 1h 客户端请求移动/使用锦囊/技能/进化 1h 把对局信息转换成可传播的信息 2h 客户端通信 3h 编写博客和文档 1h 岑 ...
- ent orm笔记2---schema使用(上)
在上一篇关于快速使用ent orm的笔记中,我们再最开始使用entc init User 创建schema,在ent orm 中的schema 其实就是数据库模型,在schema中我们可以通过Fiel ...
- 浅谈python垃圾回收机制
引入 解释器在执行到定义变量的语法时,会申请内存空间来存放变量的值,而内存的容量是有限的,这就涉及到变量值所占用内存空间的回收问题,当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉,那 ...
- 跨站请求伪造(csrf)的防护手段
CSRF CSRF全拼为Cross Site Request Forgery,译为跨站请求伪造. CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求. 造成的问题:个人隐私泄露以及财产安全. CS ...