1.对象的创建

  1) 当虚拟机遇到一条new的指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载,解析和初始化过.

  2) 在类加载检查通过后,接下来的虚拟机将为新生对象分配内存.

  3) 内存分配完成后,虚拟机需要将分配到的空间内存初始化为默认值.

  4) 接下来,虚拟机对对象进行有必要的设置,例如这个对象是哪个类的实例,如何才能找到这个类的元数据信息,对象的哈希码,对象的GC分代年龄等信息,这些信息存放在对象头.

  5) 以上工作结束后,从虚拟机角度看,对象已经创建,接下来是对对象的字段按照程序员的意思进行初始化.

2.对象的访问

  java程序需要通过栈上面的reference数据来操作堆上的具体对象.

  目前访问对象的方式有两种,一种使用句柄另一种使用直接指针:

  1) 使用句柄的话,在java堆中会划分出一块内存作为句柄池,reference中存储的就是对象的句柄地址,句柄中包含了对象的实例数据与类型数据格子的具体地址信息,这里的reference可以类比成c语言的二重指针.

  2) 使用直接指针的话,那么java堆对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference存放的就是对象的直接地址,可以类比c语言的一重指针..

  两种方法各有优劣,由于对象在堆中被移动是非常普遍的现象,前者可以只修改句柄中实例数据指针的信息,不需要修改reference的值但是它需要进行两次指针定位.后者只需要一次指针定位,速度快但是对象移动时需要修改reference的值.

3.对象的死亡

  在java中不需要程序员来管理内存,那么,我们程序中使用的实例对象在分配了空间之后何时死亡,何时回收他的内存呢?

  这里有一个很经典的算法叫做引用计数法.该算法是给对象添加一个引用计数器,每当一个地方引用便对它加一,当一个引用失效便对它减一.当计数器为0时便回收它.这个算法实现简单,判断效率高,大多数情况下是一个不错的算法,但是会这个算法无法解决两个对象相互引用的情况,比如对象A和对象B,A和B中有对方的引用,那么当其他地方的引用全部都失效之后,只剩下这两个对象的相互引用,这种情况对象AB是不会被回收的,有内存泄露的风险.

  另一个算法是可达性分析算法:这个算法是通过一系列成为"GC Roots"的对象为起点,从这些节点向下搜索,经过的路径叫做引用链,当一个对象到GC Roots没有任何引用链存在,则该对象是不可用的,应该回收.

  在java中,GC Roots对象包括:虚拟机栈(栈帧中的本地变量表)中的引用对象,方法区中类静态属性引用的对象,方法区中常量引用的对象,本地方法栈中JNI(即Native方法)引用的对象.

4.再谈引用

  从上面看到,对象是否死亡都与引用有关.JDK 1.2之后,java对引用进行了扩充:

  1) 强引用:程序代码中普遍存在的,例如"Object obj=new Object()"这类的引用,只要强引用还在,对象就不会被回收

  2) 软引用:用来描述一些非必须的但还有用的对象,软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进对象回收范围之中进行第二次回收,软引用类SoftReference.

  3) 弱引用:用来描述费必须的对象.被弱引用关联的对象会在下一次垃圾收集被回收.弱引用类WeakReference.

  4) 虚引用:虚引用完全不会对对象的生存时间构成影响,也无法通过虚引用获取对象实例.为对象设置虚引用的目的只是为了在这个对象被回收时收到一个通知.虚引用类PhantomReference.

5.生存还是死亡

  即使在可发性分析算法中不可达的对象,也不一定是死刑而是死缓.要宣告一个对象死亡,要经过至少两次标记过程:如果对象经过可达性分析后发现没有与GC Roots相连的引用链,那它会被第一次标记,并且进行一次筛选,筛选条件是此对象是否有必要执行finalzie()方法.当对象米有覆盖finalize()方法或者finalize()方法已经被虚拟机调用过,虚拟机都会视为没有必要执行.

  如果一个对象有必要执行finalize()方法,则会把这个对象放到一个F-Queue队列之中,并在稍后由虚拟机自动建立一个低优先级的Finalizer线程去执行它.这个执行是指虚拟机会触发那个方法,但是不保证会等他运行结束后.例如当主线程已经结束,Finalizer线程还未执行完,那么Finalizer将结束,不会继续执行.当Finalizer线程执行完之后,胡对F-Queue队列中的对象进行第二次标记,如果对象在finalize()方法中拯救了自己,重新与引用链上的任何一个对象建立关联(例如将自己赋给一个静态变量),第二次标记就会把它移除即将回收的集合.如果第二次依然被标记为回收,那么对象就真的会被回收.

  finalize()方法并不是C/C++中的析构函数,他运行代价高,不确定性大,无法保证各个对象的调用顺序.尽量不要使用finalize()方法.

理解JVM之对象的生命周期的更多相关文章

  1. [原创]java WEB学习笔记47:Servlet 监听器简介, ServletContext(Application 对象), HttpSession (Session 对象), HttpServletRequest (request 对象) 监听器,利用listener理解 三个对象的生命周期

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  2. 第四章 Spring.Net 如何管理您的类___对象的生命周期链

    各位,实在不好意思,因为有事,博客几天没更新了.前面有童鞋提到,配置 Objects.xml 路径的相关问题,这些东西是 IResource 接口的一些内容.在下一章会详细介绍. 传统的Net应用中, ...

  3. 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控

    如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...

  4. JVM类加载机制与对象的生命周期

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6536048.html  虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最 ...

  5. JVM的内存管理、对象的生命周期、内存泄漏

    1 JVM内存 分为“堆”.“栈”和“方法区”三个区域,分别用于存储不同的数据 1.1 堆 JVM在其内存空间开辟一个称为”堆”的存储空间,这部分空间用于存储使用new关键字所创建的对象. 1.2 栈 ...

  6. 《深入理解Java虚拟机》 Java对象的生命周期

    Java虚拟机运行时数据区 方法区:存储 类信息.常量.静态变量.即使编译器编译后的代码等数据,也有别名叫做非堆.  方法区其中有包含有 运行时常量池,用于存放编译期生成的各种字面量和符号引用.其中, ...

  7. Java虚拟机(三)垃圾标记算法与Java对象的生命周期

    前言 这一节我们来简单的介绍垃圾收集器,并学习垃圾标记的算法:引用计数算法和根搜索算法,为了更好的理解根搜索算法,会在文章的最后介绍Java对象在虚拟机中的生命周期. 1.垃圾收集器概述 垃圾收集器( ...

  8. hibernate 持久化对象的生命周期 2.1

    持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...

  9. Java 对象的生命周期

    Java对象的生命周期 在Java中,对象的生命周期包含下面几个阶段: 1.      创建阶段(Created) 2.      应用阶段(In Use) 3.      不可见阶段(Invisib ...

随机推荐

  1. CentOS7下搭建Ansible自动化运维工具,集中管理服务器

    (1).Ansible具有如下特点: 部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作: 默认使用SSH协议对设备进行管理: 主从集中化管理: 配置简单.功能强大.扩展性强: 支持A ...

  2. mysql stream read.

    Statement stmt = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY) ...

  3. Python基于正则表达式实现文件内容替换的方法

    Python基于正则表达式实现文件内容替换的方法 本文实例讲述了Python基于正则表达式实现文件内容替换的方法.分享给大家供大家参考,具体如下: 最近因为有一个项目需要从普通的服务器移植到SAE,而 ...

  4. Javascript的原型链与继承

    目录 1. ES5最经典的寄生组合式继承图 2. ES5和ES6的继承 Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类 ...

  5. 【web 安全测试Tools】BurpSuite 1.7.32及注册机【无后门版】

    BurpSuite 1.7.32 原版+注册机 下载 链接:https://pan.baidu.com/s/1LFpXn2ulTLlcYZHG5jEjyw 密码:mie3 注意无后门版文件完整性: b ...

  6. 【Kail 学习笔记】Dmitry信息收集工具

    DMitry(Deepmagic Information Gathering Tool)是一个一体化的信息收集工具.它可以用来收集以下信息: 根据IP(或域名)来查询目标主机的Whois信息 在Net ...

  7. charles 验证工具

    本文参考:charles 验证工具 验证工具/validate 验证工具 Charles可以通过发送到W3C HTML验证器,W3C CSS验证器和W3C Feed验证器来验证记录的响应. 验证报告在 ...

  8. 最新 阿里java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.阿里等10家互联网公司的校招Offer,因为某些自身原因最终选择了阿里.6.7月主要是做系统复习.项目复盘.LeetCode ...

  9. JavaScript form提交汉字乱码

    <script type="text/javascript"> var test1="http://www.w3school.com.cn/My first/ ...

  10. Java线程安全队列Queue实现原理

    原文链接:https://www.cnblogs.com/DreamRecorder/p/9223016.html 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.J ...