深入理解Java GC
一、概述
GC(Carbage Collection)垃圾收集器,由JVM自动回收已死亡的对象垃圾。
这也是Java与C++等语言的主要区别之一。
二、如何确认对象已死
1. 引用计数算法
引用计数法实现简单,效率较高,在大部分情况下是一个不错的算法。
其原理是:给对象添加一个引用计数器,每当有一个地方引用该对象时,计数器加1,当引用失效时,计数器减1,
当计数器值为0时表示该对象不再被使用。
需要注意的是:引用计数法很难解决对象之间相互循环引用的问题,主流Java虚拟机没有选用引用计数法来管理内存。
public class ReferenceCountingGC {
public Object instance = null;
private static final int ONE_MB = 1024 * 1024;
private byte[] bigSize = new byte[2 * ONE_MB];
public static void main(String[] args) {
testGC();
}
public static void testGC() {
ReferenceCountingGC objA = new ReferenceCountingGC();
ReferenceCountingGC objB = new ReferenceCountingGC();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
System.gc();
}
}
2. 可达性分析算法
主流语言(Java、C#)等都是通过可达性分析算法来判断对象是否存活。

这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,
当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。
如图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
三、垃圾收集算法
1. 标记-清除算法
标记-清除算法分为两个阶段:标记阶段和清除阶段。
- 标记阶段的任务是标记出所有需要被回收的对象。
- 清除阶段就是回收被标记的对象所占用的空间。

缺点:
- 标记和清除两个过程效率不高
- 容易产生内存碎片,碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前触发新的一次垃圾收集动作。
2. 复制算法(用于新生代)
为了解决效率问题,提出来复制算法。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。
当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,内存分配时,就不需要考虑内存碎片等问题,
只要移动堆顶指针,按顺序分配内存。实现简单、运行高效。适用于移动较少的情况。

缺点:
- 能够使用的内存缩减到原来的一半。
- 如果存活对象很多,需要很多复制操作,Copying算法的效率将会大大降低。
3. 标记-整理算法(用于老年代)
在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动(记住是完成标记之后,先不清理,先移动再清理回收对象),然后清理掉端边界以外的内存。

4. 分代收集算法
分代收集算法是目前大部分JVM的垃圾收集器采用的算法。
核心思想是根据对象存活的生命周期将堆区划分为新生代和老年代。
新生代每次垃圾收集时,都有大批对象死去,所以用复制算法。
老年代对象存活率较高,使用“标记-清除”算法或者“标记-整理“算法。
新生代和老年代的区别:
将新生代划分为一块较大的Eden空间和两块较小的Survivor空间(一般为8:1:1),每次使用Eden空间和其中的一块Survivor空间,
数据会首先分配到Eden区 当中,当Eden没有足够空间的时候就会 触发jvm发起一次Minor GC。如果对象经过一次Minor GC还存活,
并且又能被Survivor空间接受,那么将被移动到Survivor空 间当中。并将其年龄设为1。
反复将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后清理掉Eden和刚才使用过的Survivor空间。
对象每熬过一次Minor GC,年龄就加1,
当年龄达到一定的程度(默认为15)时,就会被晋升到老年代 中了,晋升老年代的年龄是可以设置的。如果老年代满了就执行:Full GC 。
深入理解Java GC的更多相关文章
- 深入理解 Java —— GC 机制
1. 基础知识 1.1 什么是垃圾回收? 程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存资源,最终将导致内存溢出,所以对内存资源的管理非常重要. 垃圾回收就是对这些无效资 ...
- 理解Java GC日志
idea 在vm options处加入-XX:+PrintGCDetails,可打印GC日志. public class ReferenceCountingGC { public Object ins ...
- Java GC回收机制
优秀Java程序员必须了解的GC工作原理 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只 ...
- jvm系列(十):如何优化Java GC「译」
本文由CrowHawk翻译,是Java GC调优的经典佳作. 本文翻译自Sangmin Lee发表在Cubrid上的"Become a Java GC Expert"系列文章的第三 ...
- 深入理解JAVA虚拟机JVM
深入理解JAVA虚拟机JVM Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制.java之所以能实现一次编写到处执行,也就是因为jVM.原理:编 ...
- jvm系列(七):如何优化Java GC「译」
本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. Sangmin Lee发表在Cubrid上的”Become a Java GC Expert”系列文章 ...
- jvm系列(十):如何优化Java GC「
转自:https://www.cnblogs.com/ityouknow/p/7653129.html 本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. ...
- 深入理解java:1.3.1 JVM内存区域的划分(运行时数据区)
学习Java GC机制,可以帮助我们在日常工作中 排查各种内存溢出或泄露问题,解决性能瓶颈,达到更高的并发量,写出更高效的程序. 我们将从4个方面学习Java GC机制, 1,内存是如何分配的: 2, ...
- Java GC(垃圾回收)机制知识总结
目录 Java GC系列 Java关键术语 Java HotSpot 虚拟机 JVM体系结构 Java堆内存 启动Java垃圾回收 Java垃圾回收过程 垃圾回收中实例的终结 对象什么时候符合垃圾回收 ...
随机推荐
- HTML 常用头部标签(meta)
先来看下常用的标签列表,后文会一一介绍: <!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --> <html lang=&quo ...
- 使用jdk的xjc命令由schema文件生成相应的实体类
xjc D:\operate-process.xsd -d D:\workspace\wmsc\src\main\java -p com.yd.wmsc.util operate-process.xs ...
- jasper_excel_sheet tab color
<property name="net.sf.jasperreports.export.xls.sheet.tab.color" value="#00FF00&qu ...
- AnkhSVN使用手册
(一) 安装: Subversion客户端安装------AnkhSVN AnkhSVN是一款在VS中管理Subversion的插件,您可以在VS中轻松的提交.更新.添加文件,而不用在命令行或资源管理 ...
- 页面上AJAX调用数据
<div class="section page9" data-page='9'> <div class="global-section-wrp med ...
- 程序代码里出现illegal character '\ufeff' 和 expected class or object definition的解决办法(图文详解)
不多说,直接上干货! 问题详情 问题分析 可能原因导致1:你的程序也许,是在他人那里复制而来,会导致这样的问题. 可能原因导致2:由于页面编码造成的. 可能原因导致1的解决办法 这个,好比,我 ...
- Promise 用es5的基础实现
只实现 then 和 catch function promise(fn) { var state = 'pending'; // 声明函数 var nowResolve = function (ar ...
- JDK工具
在之前的教程中,我曾介绍过 这些工具.现在,我向大家介绍其中最重要的5个工具. 1.javap javap是一个Java类文件反汇编程序,可以查看Java编译器生成的字节码,是分析代码的一个好工具.让 ...
- 用gethub下载ardupilot的最新源码
1进入gethub的官方网站https://github.com/作者:恒久力行 QQ:624668529 在搜索框内输入ardupilot并点击搜索点回车 2会看到很多工程,选择那 ...
- 如何下载Oracle E-Business Suite (12.2.6) for Microsoft Windows x64 (64-bit)
下载地址:https://edelivery.oracle.com/ 使用您的 Oracle 账户进行登录.如果您没有该账户, 请注册 Oracle 账户. Oracle Software D ...