理解JVM之对象的生命周期
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之对象的生命周期的更多相关文章
- [原创]java WEB学习笔记47:Servlet 监听器简介, ServletContext(Application 对象), HttpSession (Session 对象), HttpServletRequest (request 对象) 监听器,利用listener理解 三个对象的生命周期
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- 第四章 Spring.Net 如何管理您的类___对象的生命周期链
各位,实在不好意思,因为有事,博客几天没更新了.前面有童鞋提到,配置 Objects.xml 路径的相关问题,这些东西是 IResource 接口的一些内容.在下一章会详细介绍. 传统的Net应用中, ...
- 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控
如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...
- JVM类加载机制与对象的生命周期
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6536048.html 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最 ...
- JVM的内存管理、对象的生命周期、内存泄漏
1 JVM内存 分为“堆”.“栈”和“方法区”三个区域,分别用于存储不同的数据 1.1 堆 JVM在其内存空间开辟一个称为”堆”的存储空间,这部分空间用于存储使用new关键字所创建的对象. 1.2 栈 ...
- 《深入理解Java虚拟机》 Java对象的生命周期
Java虚拟机运行时数据区 方法区:存储 类信息.常量.静态变量.即使编译器编译后的代码等数据,也有别名叫做非堆. 方法区其中有包含有 运行时常量池,用于存放编译期生成的各种字面量和符号引用.其中, ...
- Java虚拟机(三)垃圾标记算法与Java对象的生命周期
前言 这一节我们来简单的介绍垃圾收集器,并学习垃圾标记的算法:引用计数算法和根搜索算法,为了更好的理解根搜索算法,会在文章的最后介绍Java对象在虚拟机中的生命周期. 1.垃圾收集器概述 垃圾收集器( ...
- hibernate 持久化对象的生命周期 2.1
持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...
- Java 对象的生命周期
Java对象的生命周期 在Java中,对象的生命周期包含下面几个阶段: 1. 创建阶段(Created) 2. 应用阶段(In Use) 3. 不可见阶段(Invisib ...
随机推荐
- Mysql读写分离(Mycat版)
(1).读写分离概述 1)工作原理 读写分离是让主数据库处理事务性增删改操作(insert.delete.update),让从数据库处理查询查询操作(select). 2)作用 1.分担负载 2.主从 ...
- PAT 甲级 1037 Magic Coupon (25 分) (较简单,贪心)
1037 Magic Coupon (25 分) The magic shop in Mars is offering some magic coupons. Each coupon has an ...
- LeetCode_122. Best Time to Buy and Sell Stock II
122. Best Time to Buy and Sell Stock II Easy Say you have an array for which the ith element is the ...
- LeetCode_112. Path Sum
112. Path Sum Easy Given a binary tree and a sum, determine if the tree has a root-to-leaf path such ...
- (二)UML之类图、接口、包
一.概念 类图(Class Diagram): 类图是面向对象系统建模中最常用和最重要的图,是定义其它图的基础.类图主要是用来显示系统中的类.接口以及它们之间的静态结构和关系的一种静态模型. 类图的3 ...
- 树形DP入门学习
这里是学习韦神的6道入门树形dp进行入门,本来应放在day12&&13里,但感觉这个应该单独放出来好点. 这里大部分题目都是参考的韦神的思想. A - Anniversary part ...
- iOS-tabBar切换不同控制器封装(自定义导航+自定义uiviewcontroler+系统自带tabbar+自定义tabbarController)
首先,一个app的搭建环境非常重要.既要实现基本功能,又要考虑后期优化的性能. 现在很多应用不仅仅是系统自带的控制器,由于需求复杂,基本上需要自定义多控制器来管理. 新建一个BasicNavigati ...
- 【c# 学习笔记】数值类型
c# 中的数值类型分为:整型.浮点型.十进制.如下图. 1.整型数值的取值范围和内存大小 类型 说明 取值范围 byte 无符号的8位整数 0到255(即2的8次方-1) sbyte 有符号的8位 ...
- 网络损伤仪细分市场:eCPRI网络损伤的技术要求
关于“网络损伤仪”的叫法 网络损伤仪,也称作为广域网仿真仪,广域网损伤仪,WAN Emulation,Network Impairment Emulator. 为什么会带WAN广域网这个限定词? 应该 ...
- linux 安装了Linux generic mysql 出错
在一次安装 Linux generic cmake 出错 提示:CMake Error: The source directory "/usr/local/src" does no ...