【JAVA秒会技术之玩搞定GC】GC算法与种类

GC算法与种类

(一)GC的概念

GC,指Ganbage Collection 垃圾回收器。GC的算法主要分为四类:引用计数法、标记清除、标记压缩、复制算法。下面将对这几种算法进行逐一说明。

(二)GC的算法——引用计数法

引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,则对象A就不可能再被使用。

 

引用计数法的问题

(1)引用和去引用伴随着加法和减法,影响性能;

(2)很难处理循环引用;

 

(二)GC的算法——标记-清除算法

标记-清除算法是现代垃圾回收算法的思想基础。标记-清除算法将垃圾回收分为两个阶段:

(1)标记阶段:通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。

(2)清除阶段:清除所有未被标记的对象。

 

(三)GC的算法——标记-压缩算法

标记-压缩算法适合用于存活对象较多的场合如老年代。它在标记-清除算法的基础上做了一些优化。和标记-清除算法一样,标记-压缩算法也首先需要从根节点开始,对所有可达对象做一次标记。但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间。

 

【引申】标记压缩对标记清除而言,有什么优势呢?

优势就是能够整理内存碎片,避免分配大对象时,空间不足导致FullGC。

(四)GC的算法——复制算法

与标记-清除算法相比,复制算法是一种相对高效的回收方法;

不适用于存活对象较多的场合 如老年代;

将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。

 

复制算法的最大问题是:空间浪费!

 

(五)分代思想

依据对象的存活周期进行分类,短命对象归为新生代,长命对象归为老年代。

根据不同代的特点,选取合适的收集算法:

①少量对象存活,比如新年代,适合复制算法。

②大量对象存活,比如老生代,适合标记清理或者标记压缩

【注意】所有的算法,需要能够识别一个垃圾对象,因此需要给出一个可触及性的定义。

(六)可触及性

(1)可触及的:从根节点可以触及到这个对象。

(2)可复活的:一旦所有引用被释放,就是可复活状态,因为在finalize()中可能复活该对象。

(3)不可触及的:在finalize()后,可能会进入不可触及状态,不可触及的对象不可能复活,可以回收。

看如下例子:

package com.liyan.gcTest;
public class CanReliveObj {
	public static CanReliveObj obj;
	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		System.out.println("CanReliveObj finalize called");
		obj = this;
	}
	@Override
	public String toString() {
		return "I am CanReliveObj";
	}

	public static void main(String[] args) throws InterruptedException {
		obj = new CanReliveObj();
		obj = null; // 可复活
		System.gc();
		Thread.sleep(1000);
		if (obj == null) {
			System.out.println("obj 是 null");
		} else {
			System.out.println("obj 可用");
		}
		System.out.println("第二次gc");
		obj = null; // 不可复活
		System.gc();
		Thread.sleep(1000);
		if (obj == null) {
			System.out.println("obj 是 null");
		} else {
			System.out.println("obj 可用");
		}
	}
}

输出结果

CanReliveObj finalize called
obj 可用
第二次gc
obj 是 null

 

【注】本文主要总结自网络共享课件,《炼数成金——深入JVM内核》作者:葛一鸣。仅供学习分享!



时间: 2024-08-30 06:10:23

【JAVA秒会技术之玩搞定GC】GC算法与种类的相关文章

【JAVA秒会技术之玩转多线程】多线程那些事儿(一)

多线程那些事儿(一)     现在只要出去面试,关于"Java多线程"的问题,几乎没有一家单位不问的,可见其重要性.于是博主抽空研究了一下,确实很有意思!以下是我综合整理了网上的各种资料,和个人的一些理解,写的一篇总结博文,仅供学习.交流. (一)多线程的概念         多线程的概念,简单理解:一个进程运行时产生了不止一个线程.         进程的概念,简单理解:正在运行的程序的实例. 两者之间的关系:进程就是线程的容器. (二)多线程的好处         使用多线程可以提

【JAVA秒会技术之玩转SQL】MySQL优化技术(一)

MySQL优化技术(一)         开发的路上,总会碰到一些老系统,越用越慢."慢"的原因也许有很多,但是,博主个人觉得,数据库的设计和sql语句写的好坏,对系统效率的影响是最直接,最显而易见的!所以,学习一下MySQL的优化,还是很有必要的.当然,博主能力有限,没那么多经验,更多的是"道听途说"和"纸上谈兵".如有不正之处,望大神开后给予指正,不胜感激! (一)MySQL优化技术概述 ①表的设计合理化(符合3NF,即符合"三范式

【JAVA秒会技术之玩转SQL】MySQL优化技术(二)

MySQL优化技术(二) [前文连接]MySQL优化技术(一) (五)常用SQL优化 1.默认情况,在使用group by 分组查询时,会先分组,其后还会默认对组内其他条件进行默认的排序,可能会降低速度.这与在查询中指定order by col1, col2类似. 如果查询中包括group by但用户想要避免排序结果的消耗,则可以使用order by null禁止排序. 例子:   2.尽量使用左连接(或右连接)来替代普通多表联查.因为使用JOIN,MySQL不需要在内存中创建临时表.    s

【JAVA秒会技术之玩转高效分页】EasyUI + PageHelper实现分页

 EasyUI + PageHelper实现分页 一.EasyUI页面分页 页面逻辑:页面初始化时,通过jquery easyui的DataGrid(数据表格)的url属性异步加载,返回指定的json格式数据,在通过pagination属性,展示分页工具栏.   表现层分析: 请求URL:/XXX/list 请求参数:Integer page.Integer rows(easyui分页控件请求的参数),其中page默认为1. 返回数据:json格式的数据(easyui分页控件请求的返回值JSON

【JAVA秒会技术之玩转图片】图片下载和等比或指定大小压缩快速实现

JAVA图片下载和等比或指定大小压缩工具类 话不多,直接上代码: package com.netease.test; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.

【JAVA秒会技术之秒杀面试官】JavaSE常见面试题(一)

[前言]别人都在你看不到的地方暗自努力,在你看得到的地方,他们也和你一样显得游手好闲,和你一样会抱怨,而只有你自己相信这些都是真的,最后,也只有你一个人继续不思进取 --   [下载]本人刚学习Java时总结的一些JavaSE常见面试题,偶尔在电脑中翻出,重新整理一下分享给需要的人,主要针对初级程序员.想要PDF完整版下载的,评论里留言留下你的邮箱! 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 答:可以有多个类,但只能有一个public的类,并且pub

【JAVA秒会技术之搞定Quartz定时任务】Quartz在Spring中的集成与应用

  Quartz在Spring中的集成与应用   一.Quqrtz简介     Quartz是一个完全由Java编写的开源任务调度的框架,通过触发器设置作业定时运行规则,控制作业的运行时间.主要用来执行定时任务,如:定时发送信息.定时生成报表等等. 简而言之,Quartz是一个定时器组件,是可以整合Spring使用的一个定时器.     二.Quqrtz的配置文件     1.在maven中引入: <dependency> <groupId>org.quartz-scheduler

【JAVA秒会技术之搞定BLOB数据类型】如何读取及展示数据库中BLOB类型的图片

如何读取及展示数据库中BLOB类型的图片    [前言]最近在做某一需求时,需要从Oracle数据库读取图片.本以为数据库存储的会是一个简单的url,前台可以直接展示,结果却发现是BLOB二进制类型,于是乎,百度/Google了关键字"二进制图片读取及展示",发现有很多"抄来抄去"的文章或博客,但是文章的质量都很低,而且结构比较混乱,看完之后仍然是"不明所以".     最后,花了近2个小时,耐心研究了一下,终于成功.于是总结如下,供大家参考,也

【JAVA秒会技术之搞定数据库递归树】Mysql快速实现递归树状查询

Mysql快速实现递归树状查询 [前言]今天一个好朋友问我的这个问题,以前也没有用到过,恰好有时间,就帮他研究了一下,纯属"现学现卖",正好在过程中,自己也能学习一下!个人感觉,其实一点也不难,不过是"闻道有先后",我们是"后"罢了.按照我的习惯,学完东西,总要总结一下嘛,也当做一个备忘录了.   具体需求就不描述了,简而言之,归结为两个: 1.如何通过子节点(cid)加载出所有的父节点(pid)? 2.如何通过父节点(pid)加载出所有的子节点