`
龙飞凤舞的程序员
  • 浏览: 1310 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

细说Java GC

 
阅读更多
GC是什么?Java初学者可能很少听到这个名词,但它的中文肯定听过:垃圾回收,英文全称为:Garbage Collection。

看过上一篇《Java虚拟机内存管理》的朋友想一下,GC的主要对象是哪几个内存区域呢?

上一篇提到,Java内存管理为5个区域,分别是程序计数器、虚拟机栈、本地方法栈、堆、方法区。其中,程序计数器、虚拟机栈中的栈帧、本地方法栈是线程独有,独立使用一块内存的。故而,它们的生命周期是和线程同步的,正所谓一定同年同月同日生,必须同年同月同日死的好兄弟啊。但是,堆和方法区,是所有线程共享使用,每个线程拥有的内存大小,都是动态的,对于它们的内存回收也是不确定的。故,GC主要是针对它们而生的。

如何判断对象是否已死?

有一个比较广泛的算法:引用计数算法。该算法描述为:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻,计数器值为0的对象,就是不可能被引用的。
像微软的COM、使用ActionScript3的FlashPlayer、Python等都是用这个算法。但是,Java是使用这个算法吗?

用如下这段代码,可以说明

/**
 * 运行这段程序,需要在运行设置的VM Arguments中写入如下语句
 * -verbose:gc
 * 它的作用是在控制台输出GC的详细信息。
 * @author qianl
 *
 */
public class Test {

	public Object instance = null;
	
	private static final int _1M = 1024 * 1024;
	
	private byte[] size = new byte[2 * _1M];	//占用一点内存,以便在GC日志中观察是否被回收过
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Test t1 = new Test();
		Test t2 = new Test();
		
		t1.instance = t2;	//t2对象被引用,如果Java使用引用计数算法,那么其值+1
		t2.instance = t1;	//t1对象被引用,如果Java使用引用计数算法,那么其值+1
		
		t1 = null;	//t1为null,它的成员变量instance所引用的对象将不会被用到。
		t2 = null;	//t2为null,它的成员变量instance所引用的对象将不会被用到。
		
		/**
		 * 在此使用Java的垃圾回收,由上面代码可知,t1和t2两个对象将不可能被用到,但是他们的引用计数的值
		 * 却不为0,它们会被回收吗?
		 */
		System.gc();
	}

}

它的运行结果为:

[GC 4408K->144K(59648K), 0.0011230 secs]
[Full GC 144K->116K(59648K), 0.0053720 secs]

注意第一句GC 4408K->144K,这说明,Java的GC,将对象回收了的。由此,可以说明,Java的GC机制,不是使用引用计数算法的。

那,JavaGC使用什么算法呢?

首先介绍一下,这个算法:根搜索算法,通过一系列名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(就是这个对象到GC Roots节点不可到达)时,则证明这个对象是不可到达的,就会被GC回收。

如下所示,其中Object7,Object8,Object9,就是被不可到达GC Roots的,就是GC回收的对象。


上面的内容,都涉及到一个名词:引用。那什么是引用?

通俗的解释为:一个reference类型的数据中存储的数值代表另外一块内存的起始地址,这块内存代表的就是一个引用。
其实,Java1.2以后,引用不止这么简单,有四种引用,分别为:强引用(如Object obj = new Object()),软引用、弱引用、虚引用。这里,我就抛砖引玉一下,大家想了解的可以Google或者度娘一下。(PS:因为我本人也不是很了解,呵呵)。

GC对方法区的回收是怎样判断的呢?

GC对于堆的回收,效率是比较高的,一次回收,基本上都可以回收百分之七八十的空间。而方法区,效率要低得多。
对于此部分,GC主要回收两部分:废弃常量和无用类。

废弃常量:如一个字符串“ABC”进入了常量池,但是系统中,没有一个String对象叫做“ABC”,即没有任何String对象引用它,那么,这个字符串就很可能被GC回收。常量池中的接口、方法、字段等都类似。

无用类:必须满足以下三个条件,才可能被GC回收
* 该类所有实例都已经被回收,即堆中不存在该类实例
* 加载该类的ClassLoader已经被回收
* 该类对应的java.lang.Class对象没有被任何地方引用,无法通过反射机制访问该类

分享到:
评论

相关推荐

    细说Java NIO

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代标准I/O(BIO)模型的新选择。NIO在Java 1.4版本引入,它为Java应用提供了高效、低延迟的数据处理方式,特别适合于高...

    细说Java之util类.

    Java中的`util`类是Java开发中不可或缺的一部分,它们提供了许多数据结构和工具类的实现,使得开发者可以方便地处理各种数据。`java.util`包是Java标准库的核心部分,包含了许多用于处理集合、时间日期、随机数生成...

    细说java线程问题

    ### 细说Java线程问题:深入理解与实践 在Java编程中,线程是执行的基本单位,它允许程序在操作系统层面并发执行多个任务。掌握Java线程的原理及其使用方法,对于提升软件性能和响应性至关重要。本文将从线程的概念...

    细说Java之常用集合类

    ### 细说Java之常用集合类 #### 一、引言 在Java开发过程中,我们经常需要处理数据的集合操作,比如存储、检索、排序等。为了方便开发者使用,Java SDK提供了一系列内置的集合类,它们主要位于`java.util`包中。...

    细说Java之常用集合类.rar

    最后,关于学习资源,"细说Java之常用集合类.pdf"这本书籍教程应该详细介绍了这些集合类的用法和实现细节,可以帮助开发者更好地理解和运用Java集合框架。"下载说明.txt"可能包含获取更多资源的指南,如"A5下载- 更...

    韩顺平细说servlet.CreateCode.java

    韩顺平细说servlet.生成验证码的代码

    《细说PHP》

    《细说PHP》作为一本面向PHP应用开发新手的入门教材,覆盖了PHP语言的基础知识和应用实践。书中内容既实用又全面,这使得它非常适合那些刚接触PHP或者准备开始PHP学习的读者。 首先,初学者需要了解的是PHP的基础...

    高洛峰php细说php4

    《细说PHP》开发Web应用程序PHP是最理想的工具,易于使用、功能强大、成本低廉、高安全性、开发速度快且执行灵活。 《细说PHP》以实用为目标设计,包含PHP开发最主流的各项技术,对每一个知识点都进行了深入详细的...

    细说servlet_笔记

    Servlet是Java EE(现在称为Java Platform, Enterprise Edition或 Jakarta EE)技术栈中的核心组件,主要用于构建Web应用程序。本文将深入探讨Servlet的相关知识点,包括它的背景、功能、在Java EE体系中的位置以及...

    细说Android 4.0 NDK编程 源码

    《细说Android 4.0 NDK编程 源码》这本书深入探讨了在Android平台上进行原生代码开发的关键技术和实践。NDK(Native Development Kit)是Google为开发者提供的一套工具,允许他们在Android应用中集成C和C++代码,以...

    兄弟连细说Linux PDF 文档

    兄弟连 细说Linux PDF文档。共12个按章节总结

    细说linux pdf

    细说linux pdf 兄弟连(lampbrother)李明linux课程pdf

    韩顺平细说servlet笔记

    J2EE(Java 2 Platform, Enterprise Edition)是Java平台上针对企业级应用的一套标准,包含了13种技术,包括Servlet、JSP、EJB等。其中,Servlet是用于接收和响应HTTP请求的服务器端组件,而JSP则负责动态生成HTML...

    细说Android4.0NDK编程.pdf

    《细说Android4.0NDK编程》由王家林所著,通过NDK,应用程序可以非常方便地实现Java与C/C++代码的相互沟通。本书顺应Android软/硬件、云计算整合潮流,详细剖析了NDK开发中涉及的各类问题和解决方案:搭建Android ...

    韩顺平细说Servlet源代码

    总的来说,《韩顺平细说Servlet源代码》这门课程涵盖了Servlet开发的核心知识点,是Java Web开发者必备的学习资料。通过学习,你可以深入理解Servlet的工作机制,提升Web应用开发的效率和质量。同时,韩顺平的讲解...

    PHP课件 细说PHP345

    PHP课件 细说PHP

    韩顺平 2011细说Servlet笔记

    Servlet是Java Web开发中的核心组件,它是一种服务器端的Java应用程序,主要用于处理和响应客户端(如Web浏览器)的请求。韩顺平老师的“2011细说Servlet笔记”是针对这一主题的深入讲解,旨在提供全面且实用的学习...

    《细说PHP》配套源码.rar

    《细说PHP》配套源码,很罕见的案例哟 /*==================================================================*/ /* 文件名:comm_pro.php */ /* 概要: 文章评论的处理页面. ...

    细说php

    细说php

Global site tag (gtag.js) - Google Analytics