【Java虚拟机】JVM学习笔记之GC
JVM学习笔记二之GC
GC即垃圾回收,在C++中垃圾回收由程序员自己来做,例如可以用free和delete来回收对象。而在Java中,JVM替程序员来执行垃圾回收的工作,下面看看GC的详细原理和执行过程。
1.对象已死?
1.1 引用计数法
Java GC不采用引用计数法是因为无法解决对象互相引用导致无法回收的问题。
1.2 可达性分析法
从GC ROOT开始搜索,搜索不到的并且经过第一次标记、清理后未复活的对象。
GC ROOT包括:
- 虚拟机栈中引用的对象
- 方法区中静态属性引用的对象
- 方法区中常量引用的对象
- Native方法引用的对象
1.3 四种引用
强引用
Object object = new Object();
只要强引用存在,就不会被回收。
软引用
描述一些还有用但是非必需的对象,当系统将要发生OOM之前,会对软引用的对象进行二次回收。
可以用SoftReference来实现软引用。
弱引用
也是用来描述一些非必需的对象,只能生存到下次垃圾回收之前,可以用WeakReference来实现。
虚引用
引用强度最弱的一种引用,可以用PhantomReference来实现虚引用。
2.垃圾回收算法
2.1 标记-清除算法
两个不足:
- 标记和清除两个阶段效率都很低
- 会造成大量的内存碎片,而为大对象分配内存需要大段的连续内存
2.2 复制算法
将内存分为两块同等大小的区域,一块用完时把上面存活的对象复制到另一块内存上,然后对这块内存进行集体回收。
这种做法的坏处是空间利用率太低。
2.3 标记-整理算法
标记整理算法是让所有存活对象都向一端移动,然后直接清理掉端外的所有内存。
2.4 分代收集算法
在现在的主流JVM中,采用的都是分代回收算法,对于经常需要回收的新生代,采用的是复制算法,而对于存活率高的老年代,采用的是标记清除和标记整理算法。
3.垃圾收集器
3.1 Serial收集器
单线程收集器,在进行垃圾收集时会停止所有其他线程,即stop-the-world。
-XX:+UseSerialGC
3.2 ParNew收集器
ParNew是Serial的多线程版本,但是还是会有stop-the-world的问题。
-XX:+UseParNewGC
3.3 Parallel Scavenge收集器
类似ParNew收集器,但是更关注系统的吞吐量,如果更注重吞吐量应该使用Parallel Scavenge收集器。
3.4 Serial Old收集器
Serial收集器的老年代版本,主要进行老年代的收集。
3.5 Parallel Old收集器
SerialOld的多线程版本。
3.6 CMS(Concurrent Mark Sweep)收集器
-XX:+UseConcMarkSweepGC
收集器是一种以获取最短回收停顿时间为目标的收集器。
但是有以下缺点:
- 由于采用多线程占用了CPU资源,可能导致系统性能下降
- 无法处理浮动垃圾:由于GC线程与用户线程同时运行,导致GC过程中还可能有垃圾产生
- 由于CMS是标记-清除算法,所以会造成内存碎片的产生
3.7 G1收集器
有如下几点特点:
- 并发与并行:通过利用多CPU、多核来减少stop-the-world的时间
- 分代回收:可以独当一面,不需要其他收集器的配合
- 空间整合:从整体上看是标记-整理算法,不同于CMS的标记-清除算法,可以有效地减少内存碎片的产生
- 可预测的停顿:采用Region进行分区,可以把一个Region分配到任意一个区域,然后会选择清理收益最高的一个Region(相比于直接清理年轻代或老年代来说清理的粒度更细,从而就导致效率提升)。
垃圾回收过程
Eden:Survivor From:Survivor TO = 8 : 1 : 1
为什么Survivor区域要分为两个:让对象在之间来回复制,从而计算对象存活的年龄。
http://ifeve.com/jvm-yong-generation/
什么时候会触发GC
由于GC是分代回收,所以这个问题分为什么时候触发Minor GC(年轻代)、Major GC(老年代)和Full GC(年轻代+老年代):
Minor GC:当Eden区域满了的时候,用户又需要创建对象,需要在堆中的年轻代分配内存,此时就会触发Minor GC。Minor GC主要采用复制收集算法,由于年轻代中的对象都很小,所以GC时间很短,经过Minor GC后没有被回收的对象会被移动到Survivor区域,并且年龄加一,当年龄超过阈值时会被移动到老年代中。
Major GC:当对象从年轻代移动到老年代之前,会检测老年代中剩余的空间是否足够装得下这些对象,所以当老年代内存不足时会触发Major GC。Major GC主要采用的标记-整理算法(CMS)。
Full GC:除了直接调用System.gc()之外,还有以下四种情况:
- 老年代内存不足
- 永生代内存不足
- CMS GC时出现promotion failed和concurrent mode failure
- 统计得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间
【Java虚拟机】JVM学习笔记之GC的更多相关文章
- java虚拟机JVM学习笔记-基础知识
最近使用开发的过程中出现了一个小问题,顺便记录一下原因和方法--java虚拟机 媒介:JVM是每一位从事Java开发工程师必须翻越的一座大山! JVM(Java Virtual Machine)JRE ...
- java之jvm学习笔记十三(jvm基本结构)
java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...
- 《深入理解Java虚拟机》学习笔记
<深入理解Java虚拟机>学习笔记 一.走近Java JDK(Java Development Kit):包含Java程序设计语言,Java虚拟机,JavaAPI,是用于支持 Java 程 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- java之jvm学习笔记三(Class文件检验器)
java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
- Java四种引用--《深入理解Java虚拟机》学习笔记及个人理解(四)
Java四种引用--<深入理解Java虚拟机>学习笔记及个人理解(四) 书上P65. StrongReference(强引用) 类似Object obj = new Object() 这类 ...
- Java虚拟机内存溢出异常--《深入理解Java虚拟机》学习笔记及个人理解(三)
Java虚拟机内存溢出异常--<深入理解Java虚拟机>学习笔记及个人理解(三) 书上P39 1. 堆内存溢出 不断地创建对象, 而且保证创建的这些对象不会被回收即可(让GC Root可达 ...
- 【Java】「深入理解Java虚拟机」学习笔记(1) - Java语言发展趋势
0.前言 从这篇随笔开始记录Java虚拟机的内容,以前只是对Java的应用,聚焦的是业务,了解的只是语言层面,现在想深入学习一下. 对JVM的学习肯定不是看一遍书就能掌握的,在今后的学习和实践中如果有 ...
随机推荐
- (转)使用Excel批量给数据添加单引号和逗号
在使用PLSQL连接oracle数据库处理数据的过程中,常用的操作是通过ID查询出数据,ID需要附上单引号,如果查询的ID为一条或者几条,我们手动添加即可,但是如果是几百条.几千条的话,就需要使用一些 ...
- (知识扩展)R运用领域一览表
• Applications and Case Studies - Lessons and Experiences • Big Data Analytics • Biomedical and Heal ...
- LintCode 406: Minimum Size
LintCode 406: Minimum Size 题目描述 给定一个由 n 个整数组成的数组和一个正整数 s ,请找出该数组中满足其和 ≥ s 的最小长度子数组.如果无解,则返回 -1. 样例 给 ...
- 【51NOD】1135 原根
[题意]给定p,求p的原根g.3<=p<=10^9. [算法]数学 [题解]p-1= p1^a1 * p2^a2 * pk^ak,g是p的原根当且仅当对于所有的pi满足g^[ (p-1)/ ...
- perl6 HTTP::UserAgent (3) JSON
如果一个 URL 要求POST数据是 JSON格式的, 那我们要怎么发送数据呢? 第一种: HTTP::Request 上一篇说到, 发送 POST 数据, 可以: . $ua.post(url, % ...
- Linux mint 18.1 / Ubuntu 16.04 安装steam
这里以Limit Mint 18.1为例: 安装steam: sudo dpkg -i steam.deb 运行后会有如下错误: 直接运行如下命令修复, 并自动启动steam: LD_PRELOAD= ...
- SQLite3数据库的操作
数据库的操作 我们在这个项目中使用的是SQLITE3数据库软件. 通过使用SQLITE3进行创建数据库,创建表,插入记录,查询记录,更新记录,关闭数据库等操作来实现将相应的数据存入数据库中. 打开数据 ...
- skb_reserve(skb,2)中的2的意义
skb_reserve() skb_reserve()在数据缓存区头部预留一定的空间,通常被用来在数据缓存区中插入协议首部或者在某个边界上对齐.它并没有把数据移出或移入数据缓存区,而只是简单地更新了数 ...
- Linux-Load Average解析(转)
load Average 1.1:什么是Load?什么是Load Average? Load 就是对计算机干活多少的度量(WikiPedia:the system Load is a measur ...
- 关于DataTable.Select不到数据的一种解决方案
网上有很多说的,试过,都没用.自己研究了一下,解决方案如下: 建立dataview,用dv.rowfilter,就可以取到了,然后TOTABLE即可. 代码如下:(只看中间那几句即可) private ...