3、JVM中的对象
1、对象的创建
A a = new A()
A:引用的类型
a::引用的名称
new A():创建一个A类对象
当创建一个对象时,具体创建过程是什么呢?
(1)JVM遇到new的字节码指令后,检查类是否被加载,否,进行类加载
(2)检查加载通过后,对新创建的对象在堆中分配内存
(3)将分配的内存空间进行初始化为0值
(4)设置对象头的信息,将对象的所属类(即类的元数据信息)、对象的HashCode、对象的GC信息、锁信息等数据存储在对象头中
(5)调用对象的构造方法进行初始化
2、对象内存的分配策略
对象创建的过程中需要为新对象在堆上划分出一块确定大小的内存空间,JVM中对于划分内存有两种策略,指针碰撞和空闲列表
指针碰撞:当内存空间绝对规整,使用中的内存放一边,未使用的内存放另一边,中间放由一个作为分界器的指针,当进行内存分配时,指针向空闲内存方向挪动与对象大小相等的距离
空闲列表:当堆上的内存空间不是绝对规整,使用和未使用的内存空间呈犬牙交错的形势,此时虚拟机需要维护一个列表,列表中记录了那块内存未被使用,分配内存时需要在列表中找到一块足够大的内存空间或分给新建的对象,并更新表中的记录。
其中指针碰撞的分配策略性能要更高一些,JVM采用哪种分配策略是由堆上内存空间是否绝对规整来决定的,内存空间是否绝对规整是由JVM采用哪种GC来决定的
给对象划分内存空间时,不仅要考虑内存的分配策略,还需要考虑到内存分配时的并发安全,JVM中是怎样确保内存分配时的并发安全呢?
JVM中创建对象十分的频繁,当对象A创建时,刚为其分配内存,还未更新指针或者列表时,对象B来创建,此时就会发生问题
JVM中为了保证并发情况下线程安全,采用了两种方案:CAS失败重试和分配缓冲
CAS失败重试:CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用到的技术,Java并发包(Java.Util.Concurrent)中的原子类都使用了CAS技术。
CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。
CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。
CAS失败重试流程:一块空白的内存,此时是null值,在空白的内存中划分出一块与申请对象大小一致的内存,划分完之后,再来看内存是否为null,是,为对象分配内存成功,否,说明在划分的过程中有别的线程来对这块内存进行了分配的操作,为对象分配内存失败,找到下一块空白的内存,继续上述操作
分配缓冲:把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在 Java 堆中预先分配一小块私有内存,也就是本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),JVM 在线程初始化时,同时也会申请一块指定大小的内存,只给当前线程使用,这样每个线程都单独拥有一个 Buffer,如果需要分配内存,就在自己的 Buffer 上分配,这样就不存在竞争的情况,可以大大提升分配效率,当 Buffer 容量不够的时候,再重新从 Eden 区域申请一块继续使用。
对象大小为8的整数倍,方便内存的划分
定位对象的方式有两种:句柄和直接指针
句柄:JVM在堆上划分出一块内存作为句柄池,引用(reference)中存储的对象就是句柄的地址,句柄中包含了对象的实例数据与类型数据真实的地址信息
优点:引用 中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而引用本身不需要修改
直接指针:引用(reference)中存储的对象就是真实地址,Sun HotSpot 是使用直接指针访问方式进行对象访问的
优点:较比句柄速度要快一些,因为它节省了一次指针定位的时间开销
6、引用的类型
强引用:一般的 Object obj = new Object() ,就属于强引用。在任何情况下,只有有强引用关联(与根可达)还在,垃圾回收器就永远不会回收掉被引用的对象
软引用:一些有用但是并非必需,用软引用关联的对象,系统将要发生内存溢出(OuyOfMemory)之前,这些对象就会被回收(如果这次回收后还是没有足够的
弱引用:一些有用(程度比软引用更低)但是并非必需,用弱引用关联的对象,只能生存到下一次垃圾回收之前,GC 发生时,不管内存够不够,都会被回收
虚引用:幽灵引用,最弱(随时会被回收掉)
7、如何判断对象是否存活
判断对象是否存活的方式有两种:引用计数法和可达性分析
引用计数法:在对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1,当引用失效时,计数器减 1
这种方法Python中使用,JVM中没有使用
可达性分析:通过以GC Roots对象为起点,向下搜索,看是否存在引用,搜索走过的路被称为引用链,当一个对象到GC Roots没有任何引用链,说明此对象是无用可被回收的
GC Roots对象:虚拟机栈(栈帧中的本地变量表)中引用的对象
各个线程调用方法堆栈中使用到的参数、局部变量、临时变量等
Finalize方法:即使通过可达性分析判断不可达的对象,也不是“非死不可”,它还会处于“缓刑”阶段,真正要宣告一个对象死亡,需要经过两次标记过程,一次是没有找到与 GCRoots 的引用链,它将被第一次标记。随后进行一次筛选(如果对象覆盖了 finalize),我们可以在 finalize 中去拯救
3、JVM中的对象的更多相关文章
- 99.9%的Java程序员都说不清的问题:JVM中的对象内存布局?
本文转载自公众号:石彬的架构笔记,阅读大约需要8分钟. 作者:李瑞杰 目前就职于阿里巴巴,资深 JVM 研究人员 在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我 ...
- JVM中的对象生命周期
在JVM运行空间中,对象的整个生命周期大致可以分为七个阶段:创建阶段(Creation).应用阶段(Using).不可视阶段(Invisible).不可到达阶段( Unreachable).可收集阶段 ...
- JVM 中的对象及引用
JVM中对象的创建过程 对象的内存分配 虚拟机遇到一条 new 指令时,首先检查是否被类加载器加载,如果没有,那必须先执行相应的类加载过程. 类加载就是把 class 加载到 JVM 的运行时数据区的 ...
- JVM中的对象
虚拟机中的对象 对象的分配 虚拟机遇到一条new指令时:根据new的参数是否能在常量池中定位到一个类的符号引用,如果没有,说明还未定义该类,抛出ClassNotFoundException: 1)检查 ...
- JVM中,对象在内存中的布局
在hotSpot虚拟机中,对象在内存中的布局可以分成对象头.实例数据.对齐填充三部分. 对象头:主要包括: 1.对象自身的运行行元数据,比如哈希码.GC分代年龄.锁状态标志等,这部分长度在32位虚拟机 ...
- JVM中判断对象是否存活的方法
Java中几乎所有的对象实例都存放在堆中,在垃圾收集器对堆内存进行回收前,第一件事情就是要确定哪些对象还“存活”,哪些对象已经“死去”(即不可能再通过任何途径被使用). 引用计数算法 首先需要声明,至 ...
- Hibernate 系列 06 - 对象在JVM中的生命周期
引导目录: Hibernate 系列教程 目录 Java对象通过new命令进行创建,Java虚拟机(Java Virtual Machine,JVM)会为新的Java对象在内存中开辟一个新空间以存放次 ...
- JVM中对象的创建过程
JVM中对象的创建过程如以下流程图中所示: 对其主要步骤进行详细阐述: 为新生对象分配内存: 内存的分配方式: 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存在另一边, ...
- 《深入Java虚拟机学习笔记》- 第7章 类型的生命周期/对象在JVM中的生命周期
一.类型生命周期的开始 如图所示 初始化时机 所有Java虚拟机实现必须在每个类或接口首次主动使用时初始化: 以下几种情形符合主动使用的要求: 当创建某个类的新实例时(或者通过在字节码中执行new指令 ...
随机推荐
- 用 Python 写个七夕表白神器
今天是七夕节,相比于现代人自创的 502,不对是 520,七夕才是中国传统意义上的情人节,本文分享几个 Python 表白程序,情侣可以现学现用,单身的话也可以先收藏一下,说不定下次就用上了. 爱心树 ...
- Hadoop 3.x 与Hadoop 2.x 的区别和优化点
Hadoop 3.x 与Hadoop 2.x 的区别和优化点 通用性 1.精简Hadoop内核,包括剔除过期的API和实现,将默认组件实现替换成最高效的实现(比如将FileOutputCommitte ...
- 求求大厂给个Offer:Map面试题
前言 文本已收录至我的GitHub:https://github.com/ZhongFuCheng3y/3y,有300多篇原创文章,最近在连载面试系列! 我,三歪,最近开始写面试系列.我给这个面试系列 ...
- SEO外包好还是自己组建团队
http://www.wocaoseo.com/thread-151-1-1.html 营络营销已成为企业不可忽视的一块大肥肉,很多企业都想进来分一杯羹,但是不少企业苦于缺少过硬的技术,无 ...
- WPF Devexpress 控件库中ChartControl 实现股票分时走势图
概要 从事金融行业开发 ,会接触些图表控件,这里我分享一下自己基于DevExpress.Charts.v16.2开发的股票分时走势图的经验. 附上源码:点击跳转 如果需要讨论,Q群:580749909 ...
- python IDE(集成开发环境)——PyCharm的安装
选择PyCharm的原因: 1.很多大佬都推荐,说适合实战操作项目 2.另外是界面可视化不错,颜色很舒服(体验完之后的感觉) 3.PyCharm本身有很多操作快捷键很方便(后续可以记下来常用的,方便自 ...
- Python Selenium 之数据驱动测试的实现
数据驱动模式的测试好处相比普通模式的测试就显而易见了吧!使用数据驱动的模式,可以根据业务分解测试数据,只需定义变量,使用外部或者自定义的数据使其参数化,从而避免了使用之前测试脚本中固定的数据.可以将测 ...
- 我们真的需要JWT吗?
JWT(JSON Web Token)是目前最流行的认证方案之一.博客园.各种技术公众号隔三差五就会推一篇JWT相关的文章,真的多如牛毛.但我对JWT有点困惑,今天写出来跟大家探讨探讨,不要喷哈. J ...
- Namomo Cockfight Round 5
AC代码 A. Number 假设\(n_i\)为十进制数\(n\)的第\(i\)位上的数字,那么\(\max_{i}n_i\)即为答案. B. Mod 用BFS的方法计算可以以\(O(p)\)的复杂 ...
- 20190923-13Linux企业真实面试题 000 021
百度&考满分 问题:Linux常用命令 参考答案:find.df.tar.ps.top.netstat等.(尽量说一些高级命令) 瓜子二手车 问题:Linux查看内存.磁盘存储.io 读写.端 ...