JVM中对象的销毁
1、可达性分析算法:
可达性分析算法用来寻找将要销毁的对象,它的基本思路是:通过一系列的称为“GC ROOTs”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象到GC ROOTs没有任何引用链想连时,则证明此对象是不可用的。如下图所示:

对象 object5/object6/object7 虽然相互关联,但它们到GC Roots 是不可达的,所以它们会被判定为可回收的对象。
在 Java 语言中,可作为GC Roots的对象包括下面几种:
·虚拟机栈(栈帧中的本地变量表)中引用的对象
·本地方法栈中 Native方法 引用的对象
·方法区中类静态属性引用的对象
·方法区中常量引用的对象
2、宣判对象死亡的过程:
此过程以流程图的形式表示更为直观:

F-Queue 队列的执行,是由一个虚拟机自动建立的、低优先级的 Finalizer 线程执行的。这里的执行是指虚拟机会触发这个方法,但不保证会等待方法执行结束,这样是为了防止 Finalizer 执行缓慢或发生死循环,进而引起 F-Queue 队列中其他对象永久等待,甚至整个内存回收系统崩溃。
下面给出一段 finalize() 被执行但对象仍然存活的示例:
/**
* 此代码演示了两点:
* 1.对象可以在被GC时自我拯救
* 2.这种自救的机会只有一次。因为一个对象的 finalize()方法最多只会被系统自动调用一次
* @author yangtf
*
*/
public class FinalizeEscapeGC {
public static FinalizeEscapeGC SAVE_HOOK = null; public void isAlive(){
System.out.println("Yes,I am still alive");
} @Override
protected void finalize() throws Throwable{
super.finalize();
System.out.println("finalize method executed!");
FinalizeEscapeGC.SAVE_HOOK = this; // 将自己赋值给 SAVE_HOOK
} public static void main(String[] args) throws InterruptedException {
SAVE_HOOK = new FinalizeEscapeGC(); // 对象第一次成功拯救自己
SAVE_HOOK = null;
System.gc(); // finalize方法优先级很低,所以暂停0.5秒以等待它
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, I am dead");
}
}
}
执行结果:
finalize method executed!
Yes,I am still alive
No, I am dead
从结果可以看出,SAVE_HOOK 对象的 finalize() 方法确实被GC收集器触发过,并且在被收集前成功逃脱了。
执行第二次失败,因为任何一个对象的 finalize() 方法都只会被系统自动调用一次,如果对象面临下一次回收,它的 finalize() 方法不会被再次执行,因此第二段代码的自救失败。
3、对象的引用
JDK1.2后,Java 将对象引用概念进行扩张,将其分为:强引用、软引用、弱引用、虚引用,四种引用强度依次减弱。
1)强引用:代码中普遍存在,类似“Object obj = new Object()”。只要强引用还存在,垃圾收集器永远不会对其引用的对象进行回收。
2)软引用:用来描述还有用,但并非必须的对象。对软引用关联的对象第一次不回收,若第一次回收之后内存仍不够,则将其回收;即进行第二次回收。
3)弱引用:比软引用更弱的引用。第一次垃圾回收就会将其回收。
4)虚引用:也称为幽灵引用或幻影引用。一个对象是否有虚引用存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用的唯一目的,就是能在这个对象被收集器回收时收到一个系统通知。
JVM中对象的销毁的更多相关文章
- JVM中对象的回收过程
当我们的程序开启运行之后就,就会在我们的java堆中不断的产生新的对象,而这是需要占用我们的存储空间的,因为创建一个新的对象需要分配对应的内存空间,显然我的内存空间是固定有限的,所以我们需要对没有 ...
- JVM中对象的创建过程
JVM中对象的创建过程如以下流程图中所示: 对其主要步骤进行详细阐述: 为新生对象分配内存: 内存的分配方式: 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存在另一边, ...
- Java虚拟机笔记(五):JVM中对象的分代
为什么要分代 为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用, ...
- 学习一下 JVM (二) -- 学习一下 JVM 中对象、String 相关知识
一.JDK 8 版本下 JVM 对象的分配.布局.访问(简单了解下) 1.对象的创建过程 (1)前言 Java 是一门面向对象的编程语言,程序运行过程中在任意时刻都可能有对象被创建.开发中常用 new ...
- JVM中对象访问定位两种方式
1.通过句柄方式访问, 在Java堆中分出一块内存进行存储句柄池,这样的话,在栈中存储的是句柄的地址 优点: 当对象移动的时候(垃圾回收的时候移动很普遍),这样值需要改变句柄中的指针,但是栈中的指针不 ...
- @JVM中对象的引用类型
JVM中有四种引用类型:强引用.软引用.弱引用.虚引用 强引用(Stong Reference):是指在程序代码中普遍存在的,类似:Object obj = new Object()这类的引用,只 ...
- JVM中对象的内存布局与访问定位
一.对象的内存布局 已主流的HotSpot虚拟机来说, 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填 ...
- JVM中对象是否已死
- 《深入Java虚拟机学习笔记》- 第7章 类型的生命周期/对象在JVM中的生命周期
一.类型生命周期的开始 如图所示 初始化时机 所有Java虚拟机实现必须在每个类或接口首次主动使用时初始化: 以下几种情形符合主动使用的要求: 当创建某个类的新实例时(或者通过在字节码中执行new指令 ...
随机推荐
- linux系统root用户忘记密码的重置方法
如果不小心忘记了新安装的lCentOS7的root密码,现在将找回过程分享给大家. 1.首先,在启动grub菜单,选择编辑选项启动: 2.然后,按e 进入编辑模式: 3.将'linux 16'行'ro ...
- Adobe illustrator & Photoshop 处理图片
Adobe illustrator 置入,可以将多张图片放在一张纸 (一个sheet)里面. Adobe photoshop: 新建一个图层,然后置入,将图片导入,然后裁剪,最后另存为就可以得到最后的 ...
- 测试css
<h1>shell使用指南</h1> <h2>ZMODEM功能</h2> <pre><code>yum install lrzs ...
- wpf 悬浮窗口的实现
又到了写点东西的时候,因为有了新的收获,所以用随笔来记录下自己的成长.话不多说,正入主题. 最近又遇到一个新的需求,有一组控件,需要悬浮显示在面板的边缘上,刚开始的时候,是不显示的,点击后显示,然后再 ...
- Delphi多线程的OnTerminate属性(附加一个关于临界区线程同步的例子)
首先看TThread源码中关于OnTerminate的代码: public .... property OnTerminate: TNotifyEvent read FOnTerminate writ ...
- JavaScript 字符串处理详解
一.创建字符串 创建一个字符串,将一组字符串用引号包起来,将其赋值给一个字符串变量. var JsStr="Hello,JavaScript String!"; 二.字 ...
- Entity Framework 6 Database-first连接Oracle11g
Entity Framework 6 Database-first连接Oracle11g(图文细说) 本文发布地址:http://www.cnblogs.com/likeli/p/5577264.ht ...
- Log4Net记录日志的使用
Log4net 基本样式: <log4net> <appender name="LogFileAppender" type="log4net.Appen ...
- IO(1)
java的IO主要在java.io包下,包括字节流和字符流. 1 File File类可以对文件和目录进行操作,就是不能访问文件本身,其常用方法包括: 1)String getName(),返回fil ...
- http错误代码含义中英文对照
Http错误代码含义中文 概要当用户试图通过 HTTP 或文件传输协议 (FTP) 访问一台正在运行 Internet 信息服务 (IIS) 的服务器上的内容时,IIS 返回一个表示该请求的状态的数字 ...