• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

sou78

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

java垃圾回收器-判断对象存活算法

1.引用计数算法

给对象中添加一个引用计数器,每当一个地方引用它时,计数器就加1,;当引用失效时,计数器就减1;任何时刻计数器为0的对象就是不可能再被使用的。

2.根搜索算法

通过一系列的名为“GC Roots”的对象作为起点,从这些起点开始乡下搜索,搜搜所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

GC Roots的对象包括以下几种:

虚拟机栈中的引用的对象

方法区中的类静态属性引用的对象及常量

本地方法栈中JNI的引用的对象

在跟搜索算法中不可达的对象,也并非是非死不可的,这时候他们暂时处于缓刑阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行跟搜索后发现没有与之相连的,就标记它并且进行一次帅选,帅选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过...

懒着抄了,看个例子

public class FinalizeEscapeGC {
	public static FinalizeEscapeGC SAVE_HOOK = null;
	
	public void isAlive() {
		System.out.println("yes, i am still alive:");
	}
	protected void finalize() throws Throwable {
		super.finalize();
		System.out.println("finalize method executed");
		FinalizeEscapeGC.SAVE_HOOK = this;
	}
	public static void main(String[] args) throws InterruptedException  {
		SAVE_HOOK = new FinalizeEscapeGC();
		SAVE_HOOK = null;
		System.gc();
		Thread.sleep(500);
		if (SAVE_HOOK != null) {
			SAVE_HOOK.isAlive();
		} else {
			System.out.println("no , i am dead");
		}
		SAVE_HOOK = null;
		System.gc();
		Thread.sleep(500);
		if (SAVE_HOOK != null) {
			SAVE_HOOK.isAlive();
		} else {
			System.out.println("no , iamdead");
		}
	}
}

输出结果:

finalize method executed
yes, i am still alive:
no , iamdead

可以看出,第一次对象自救成功了,可是第二次同样的代码,对象却自救失败了。原因在于jvm只会调用finalize()方法一次,如果对象面临下一次回收时,他的finalize·()方法就不会被再次执行。

3.回收方法区

常量跟堆中的回收差不多。对于无用的类,需要满足一下条件:

该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例。

加载该类的ClassLoader已经被回收

该类对应的java.lang.class对象没有在任何地方被应用

 

posted on 2013-09-25 14:46  sou78  阅读(678)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3