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. 怎样加入社区项目Karbor的Review?

    Review是社区衡量一个贡献者的重要标准. Review步骤: 1.登录Karbor Review地址: https://review.openstack.org/#/q/Karbor 这里可以看到 ...

  2. python面向对象之初步认识

    面向对象 类,用来描述一类事物的相同的特征或者属性.比如说,狗,狗属于一种统称,狗还分有不同的种类,比如,牧羊犬,蝴蝶犬,京巴等等,他们都有相同的特征,一个头,两个耳朵,四条腿,会跑,会吃东西,会汪汪 ...

  3. 单点登录系统(SSO)详细设计说明书(上篇)

    1.引言 1.1编写目的 为了单点登录系统(SSO系统)的可行性,完整性,并能按照预期的设想实现该系统,特编写需求说明书.         同时,说明书也发挥与策划和设计人员更好地沟通的作用. 1.2 ...

  4. 创建.Net Core For WPF项目并且添加VS Code编译运行支持

    1.下载最新的Visual Studio 2019或者Preview版本,新建项目,找到"WPF App(.Net Core)"模板. 2.输入项目名称"NetCore- ...

  5. SSRF——weblogic vulhub 漏洞复现及攻击内网redis(一)(附批量检测脚本)

    0X01 概述 SSRF(Server-Side Request Forgery, 服务端请求伪造)利用漏洞可以发起网络请求来攻击内网服务.利用SSRF能实现以下效果:1)        扫描内网(主 ...

  6. vue警告: component lists rendered with v-for should have explicit keys

    warning信息:component lists rendered with v-for should have explicit keys. See https://vuejs.org/guide ...

  7. 判断scrollView的滑动方向(二)

    在上一篇文章<判断scrollView的滑动方向>中谈到的第二种方法是根据滑动速率来判断的. 今天将通过滑动过程中的坐标差来判断 - (void)scrollViewDidScroll:( ...

  8. Windows 10系统快捷键

    虚拟桌面 创建新的虚拟桌面:Win + Ctrl + D 关闭当前虚拟桌面:Win + Ctrl + F4 切换虚拟桌面:Win + Ctrl +左/右 任务视图:Win + Tab Win10常用W ...

  9. python while循环 - python基础入门(9)

    经过昨天的学习,相信大家已经对 python的条件判断表达式if/else 有一定的了解了,那么我们今天配合昨天的课程讲解一个新概念 – while循环 . 都说程序源于生活,假如有这样一个场景:老师 ...

  10. [翻译向] 当flush privileges生效时

    #前言: 最近频繁在mysql权限控制这里栽跟斗,在翻阅了一些资料之后,简单地翻译一下官网关于flush privileges的描述,抛砖引玉.   #翻译正文: If the mysqld serv ...