JAVA垃圾收集机制

原创 2015年11月19日 23:03:34

一。哪些内存需要回收:

       java使用的不是引用计数法。

如果两个对象互相引用,引用计数不为0,那么就无法回收这些对象。

java使用的是:可达性分析(Reachability Analysis),这个算法的思想是通过一系列的称为“GC Roots”的对象作为起点,从这些起点开始往下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何的引用链,相连接时,则证明这个对象是不可引用的。


 

可以作为GC ROOT的对象可以包括以下几种:

1.虚拟机栈中引用的对象

2.方法区中类静态属性引用的变量

3.本地方法区中常量引用的变量

4.本地方法栈中JNI(及一般说的Native方法)引用的对象。

二、被标记需要清除对象的自我救赎

       上一章讲了java垃圾收集机制是基于 GcROOT可达性分析,那么这章要说的是,即使没有通过可达性分析的对象,也并非是“非死不可”。

第一轮筛选:如果对象在可达性分析中没有于GcROOT链相连,那么就需要进行第二轮筛选

第二轮筛选:对象有没有覆盖(override)过 finalize()函数,对象是否还没运行过finalize()函数。如果这连个条件都满足,

那么对象就会判断为有必要执行finalize()函数,并把这个对象放入到一个叫做F-Queue的队列中,

稍后GC会对这个队列中的对象进行第二次扫描,执行每个对象的finalize()函数,那么如果对象要在这里拯救自己——只要在finalize()函数中让自己重新与GcROOT的任何一个对象建立连接即可。

譬如把自己(this关键字)赋值给某个类变量或者对象的成员变量,那么在这第二次筛选中就会将这个对象移出出“即将回收”的集合


如下代码:

package test;

public class FinalizeEscapeGC {
	public static FinalizeEscapeGC SAVE_HOOK = null;
	
	public void isAlive(){
		System.out.println("the object is alive");
	}
	
	protected void finalize() throws Throwable {
		super.finalize();
		System.out.println("finalize method is excuted");
		FinalizeEscapeGC.SAVE_HOOK = this;
	}
	
	public static void main(String[] args) {
		SAVE_HOOK = new FinalizeEscapeGC();
		SAVE_HOOK = null;
		System.gc();
		try {
            //因为finalize方法的优先级很低,所以等待0.5秒以等待它
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if(SAVE_HOOK != null){
			SAVE_HOOK.isAlive();
		} else {
			System.out.println("no , I am dead");
		}
	}
}

最后运行的结果是:

finalize method is excuted
the object is alive

可以看到最后这个对象自我拯救成功。

三、垃圾收集的算法

       上一章我们讲了一个对象要确认被垃圾回收,需要经过两次筛选 1:GCROOT可达性分析,2:对象是否在finalize()方法中自我拯救。那么这一章将具体介绍一下垃圾收集的算法

1.标记-清除 算法

①标记出所有需要回收的对象。

②标记完成后,统一回收所有被标记的对象。

缺点是:①:标记和收集的两个过程效率都不高。②:标记清除后会产生大量的不连续的内存空间,空间碎片多了以后就无法分配大块的内存空间给大的对象使用。

标记清除算法:


2.复制算法:

将内存分为大小相同的两部分,只在其中的一部分内分配内存,当这一部分内存用完需要垃圾回收的时候,就将这部分内存中还存活的对象复制到另一部分内存中。然后再将使用过的这部分内存一次性清空。就是对整个半区进行回收。

内存回收前:


内存回收后:


那么这种复制算法的好处就是 高效,也不用考虑内存碎片等复杂的问题。

缺点就是每次只能使用一半的内存,未免太浪费了。好消息是,对于新生代的对象来说大部分都是很快就死去了,所以剩下存活的对象寥寥无几,所以我们没有必要按1:1的比例来分,HotSpot虚拟机的默认分配比例是8:1

3.标记——整理算法:

我们上面介绍的 复制算法 在对象存活率较高的情况下就要进行较多此的垃圾回收,显然不适合,那么对于对象存活率较高的情况 我们可以使用另外一种算法:

标记——整理算法。其中标记过程和我们介绍的第一个“标记——清除”算法一样。但是后续步奏不是直接对对象进行回收,而是让所有存活的对象都向其中的一端移动,然后直接清除掉端边界外的内存。


那么介绍完上面这些收集算法之后,我们要知道它们在java虚拟机中使用的地方是不一样的。

java一般将内存分为 新生代 和 老年代

新生代对象的存活率低,可以使用 复制算法 回收内存

而老年代的对象存活率高,可以使用 标记——整理 算法来回收内存

 

参考书本:《深入理解Java虚拟机 JVM高级特性与最佳实践》更详细内容,请参考书本


版权声明:本文为博主原创文章,未经博主允许不得转载。

java垃圾收集机制(GC)

java GC机制主要完成3件事:确定那些内存要回收,确定什么时候需要执行GC,如何执行GC。我们从四个方面学习GC机制:1,内存是如何分配的。2,如何>保证内存不被错误回收(即为:那些内存需要回收)...
  • yubotianxiao
  • yubotianxiao
  • 2016年06月22日 09:49
  • 726

垃圾收集机制的批判

垃圾收集机制的批判[原创] myan 2004-05-26 在Java版发表这篇文章,似乎械惆衙分赶騄ava了。其实不是,GC是所有新一代语言共有的特征,Python, Eiffel,C#,Roby...
  • Flyingfoxoo
  • Flyingfoxoo
  • 2004年06月07日 09:51
  • 600

PHP 的垃圾收集机制

PHP 的垃圾收集机制是怎样的 PHP作为脚本语言是页面结束即释放变量所占内存的。 当一个 PHP线程结束时,当前占用的所有内存空间都会被销毁,当前程序中所有对象同时被销毁。GC进程一般都跟着每...
  • ssdfsfdf
  • ssdfsfdf
  • 2016年03月04日 17:49
  • 268

java垃圾收集方法

Java内存区域中,其中程序计数器、虚拟机栈、本地方法栈s
  • guo_net
  • guo_net
  • 2014年09月10日 15:40
  • 843

《Java Performance》笔记2——JVM命令行选项及垃圾收集日志解析

1.JVM命令行选项: HotSpot VM运行时系统解析命令行选项,并据此配置HotSpot VM, HotSpot的命令行选项主要有3类: A. 标准选项: JVM规范要求所有的JVM都必...
  • chjttony
  • chjttony
  • 2015年05月21日 20:24
  • 1835

Java垃圾收集机制(一)

一、内存回收对象 1、
  • cdu09
  • cdu09
  • 2014年04月13日 17:22
  • 670

JAVA垃圾收集机制剖析

1.垃圾收集算法的核心思想   Java语言建立了垃圾收集机制,用以跟踪正在使用的对象和发现并回收不再使用(引用)的对象。该机制可以有效防范动态内存分配中可能发生的两个危险:因内存垃圾过多而引发...
  • lifuxiangcaohui
  • lifuxiangcaohui
  • 2014年05月08日 16:04
  • 1252

第八篇:Java垃圾收集机制

对象引用     Java中的垃圾回收一般是在Java堆中进行,因为堆中几乎存放了Java中所有的对象实例。谈到Java堆中的垃圾回收,自然要谈到引用。在JDK1.2之前,Java中的引用定义很很纯...
  • u012426327
  • u012426327
  • 2017年08月17日 09:09
  • 111

Java的垃圾收集机制

通常,我们把分配出去后,却无法回收的内存空间称为"内存渗漏体(Memory Leaks)"。   以上这种程序设计的潜在危险 性在Java这样以严谨、安全著称的语言中是不允许的。但是Java语言...
  • inaoen
  • inaoen
  • 2011年03月28日 17:13
  • 418

Java垃圾收集机制

 Java垃圾收集机制 佟强 2008.10.29Java使用垃圾收集器来收集不再使用的对象的存储空间一个对象没有引用指向它的时候被认为是不再使用的Java虚拟机自动选择合适的时机进行垃圾收集程序也可...
  • microtong
  • microtong
  • 2008年10月30日 00:01
  • 1399
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA垃圾收集机制
举报原因:
原因补充:

(最多只允许输入30个字)