JVM垃圾收集(GC)机制和GC算法
垃圾收集(Garbage Collection)机制
- 前言
- 1.GC需要回收哪些内存?
- 2.回收的基本单位?
- 1.标记:判断对象生死
- (1)引用计数法(Python中使用,这里做简单介绍)
- (2)可达性分析(Java中使用)
- 2.回收:把死的对象回收回去
- (1)标记-清除算法
- (2)标记-复制算法
- (3)标记-整理算法
前言
垃圾收集(Garbage Collection)简称GC。
1.GC需要回收哪些内存?
主要回收堆,其次是方法区,栈中不需要回收,线程结束,栈上的内存就会被释放。
2.回收的基本单位?
内存的单位是“字节”,但回收是按“对象”为单位进行的。
1.标记:判断对象生死
垃圾收集器在对堆进行回收之前,第一件事就是要确定堆中的对象是否“存活”,因此我们需要用标记的方法来给对象打上“生死标签”。
判断对象生死有下面两种方法:
(1)引用计数法(Python中使用,这里做简单介绍)
众所周知,创建一个对象,它必须被引用才会有意义,不然如何寻找这个对象呢?
所谓的引用计数法,就是在对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加一;当引用失效时,计数器的值就减一;任何时刻计数器为零的对象就不可能再被使用了,此时该对象就会被标记。
优点:
原理简单,判定效率高效。缺点:
致命缺点,它无法解决对象之间相互引用的问题。
举一个例子:
public class Test1 {public Object o1 = null;public static void testGC(){//创建完成时两个对象的引用计数器都为1Test1 A = new Test1(); //假设A指向对象1Test1 B = new Test1(); //假设B指向对象2//两个对象相互循环引用(此时两个对象的引用计数器都为2)A.o1 = B;B.o1 = A;//让两个引用为空(此时计数器减一,两个对象的引用计数器都为1)A = null;B = null;}
}
此时我们再想使用对象1和对象2时已经不可能了:当我想找对象1的引用时,发现该引用在对象2中;当我想找对象2的引用时,发现该引用在对象1中。所以说这两个对象已经废了,但如果用引用计数法来标记的话,它们却还是活着的对象,这就是引用计数法的最大缺陷。
(2)可达性分析(Java中使用)
Java中是通过可达性分析(Reachability Analysis)算法来判定对象是否存活,这个算法的基本思路是通过一系列被称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走的过程称为“引用链”,如果某个对象到“GC Roots”间没有任何引用链相连,也就是不可达时,则证明此对象不可能再被使用。
图中对象object5、object6、object7都是不可达的,因此它们都将被判定为可回收的对象。
从可达性分析的定义中可以看到“GC Roots”这个根对象是一个节点集,因此可以作为根对象并不是只有一个节点,而是有一个集合。
在Java中固定可以作为GC Roots的对象包括但不限于以下几种:
- 在方法区中类静态属性引用的变量,比如:Java类的引用类型静态变量
- 在方法区中常量引用的对象,比如:字符串常量池中的引用
- Native方法引用的对象
2.回收:把死的对象回收回去
知道垃圾是谁了,那么接下来就是清理垃圾的过程,Java中的垃圾收集算法有三种:标记-清除算法、标记-复制算法、标记-整理算法。从名字我们就可以看出来标记的必要性了。
(1)标记-清除算法
如它的名字一样,该算法分为两个阶段:“标记”和“清除”。首先标记处所有需要回收的对象,再统一回收被标记的对象;或者反过来,标记存活的对象,回收未被标记的对象。该算法是最基础的收集算法。
优点:
效率高(但是缺点也和效率有关)
缺点:
1.效率不稳定。试想一下如果我们在标记过程中,正好标记的是那些“大多数”,再往极限想,全部都要标记,那标记的过程就是一个极其耗时的过程。
2.内存空间的碎片化。当完成标记和清除操作后,内存空间会产生大量的不连续内存碎片(就像删除数组中的元素却不移动其他元素一样),这就可能导致今后我们在给一个大对象分配空间时找不到一个足够大的连续内存而不得不再出发另外一次垃圾收集。
(2)标记-复制算法
也是“人”如其名,常被简称为复制算法。是为了解决标记-清除算法的缺点被提出的。它将可用的内存分为大小相等的两份,每次只使用其中一块,这一块的内存用完了,就将存活的对象复制到另外一块上,然后再把已使用的那一块内存一次性清理掉。这样就解决了标记-清除算法的效率不稳定和内存空间碎片化的问题。
优点:
实现简单,运行高效
缺点:
严重浪费内存空间
(3)标记-整理算法
所谓标记-整理算法,就是标记-清除算法的另外一个改进版本,顾名思义:标记完成后先将所有存活的对象往内存空间的一端移动,然后直接清除掉边界以外的内存。
优点:
解决了内存空间碎片化的问题
缺点:
移动存活的对象是一种极其负重的操作,而且想移动存活的对象必须先全程暂停用户应用程序才能进行。像这种停顿被描述为"Stop The World"。
JVM垃圾收集(GC)机制和GC算法相关推荐
- JVM内存区域(Java内存区域)、JVM垃圾回收机制(GC)初探
一.JVM内存区域(Java内存区域) 首先区分一下JVM内存区域(Java内存区域)和Java内存模型(JMM)的概念.Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Ja ...
- 彻底搞懂GC机制和GC算法
1. 分代 堆中内存分为新生代和老年代,其中新生代又分为Eden区.(Survivor)From区.(Surviver)To区,大致如图: 2. GC分类 2.1 新生代垃圾回收器:Minor GC/ ...
- JVM虚拟机(四):JVM 垃圾回收机制概念及其算法
垃圾回收概念和其算法 谈到垃圾回收(Garbage Collection)GC,需要先澄清什么是垃圾,类比日常生活中的垃圾,我们会把他们丢入垃圾箱,然后倒掉.GC中的垃圾,特指存于内存中.不会再被使用 ...
- jvm垃圾回收机制和常见算法
这是朋友给的面试题里边的,具体地址已经找不到,只能对原作者说声抱歉了: 理论上来讲sun公司只定义了垃圾回收机制规则,而步局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同. GC(Gar ...
- JVM 垃圾回收机制和常见算法
理论上来讲 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同. GC(Garbage Collector)在回收对象前首先必须发现那些无用的对象, ...
- JVM成神路之GC基础篇:对象存活判定算法、STW、GC种类详解
引言 在前面分析JVM运行时内存区域时,其中程序计数器.虚拟机栈.本地方法栈三个区域随线程而生,伴线程而亡.而运行期间,栈的每个栈帧所需空间大小,其实在编译期就可大致确定,因此这几个区域的内存分配和回 ...
- (六)JVM成神路之GC基础篇:对象存活判定算法、GC算法、STW、GC种类详解
引言 经过前面五个章节的分析后,对于JVM的大部分子系统都已阐述完毕,在本文中则开始对JVM的GC子系统进行全面阐述,GC机制也是JVM的重中之重,调优.监控.面试都逃不开的JVM话题. 在前面分析J ...
- 32位jdk最大内存_你了解Java 内存区域和GC机制吗?
目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...
- 转载:Java 内存区域和GC机制
原文链接:http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html 目录 Java垃圾回收概况 Java内存区域 Java对象的访 ...
最新文章
- The Elements of C# Style -Naming
- 修改远程桌面连接端口
- 华为鸿蒙系统手机销量,两个品牌助力华为新生,但最终会是谁拯救谁
- max格式转obj小工具_Python写图片格式批量处理工具!你还一张一张转格式吗?
- win7的python3.5安装numpy包
- 值转换成布尔类型的False;
- [论文阅读] Learning a Unified Classifier Incrementally via Rebalancing
- (最简单的)在VS中调用存储过程
- 计算机启动dos,开机怎么进入dos_开机怎么进入dos界面
- C语言求等腰梯形面积,几道C语言的题目!
- 如何在电脑上使用wink一键高清优化短视频画质
- [UGUI源码剖析]—Rebuild 网格重建(画布刷新)系统
- aspose.word删除分页符
- codeforces 300B切题记录
- 理财就是理生活 —— 小白理财训练营(上)
- 如何删除已被谷歌收录的404错误页面
- bootstrap图片叠加_详解Bootstrap四种图片样式
- 电信运营商知多少(美国篇)
- iOS进阶课程-Passbook编程-关东升-专题视频课程
- 历史上的今天5月5日的重大事件