JVM hotspot虚拟机对象探秘
为什么80%的码农都做不了架构师?>>>
本文全部内容均转述自《深入理解Java虚拟机 JVM高级特性与最佳实践(第二版)》2.3节 下载地址:http://pan.baidu.com/s/1jIFqx74 密码:t517
主要讲述的内容主要是在常用的HotSpot虚拟机中,对象是如何在堆内存中分配,布局和访问的。
分配
Java面向对象,时时刻刻有对象被创建出来。在语法上,我们通过new
关键字可以创建一个新的对象。而当虚拟机遇到new
时,会通过以下步骤创建一个对象,并为之分配内存:
- 【类加载检查】检查常量池是否能定位到
类的符号引用
。如果对应的类没有被加载
、解析
和初始化
,则执行相应过程。 - 【分配内存】在前一个步骤已经知道类对应的对象所需的内存大小,这一步要做的是
找到合适大小的内存空间
。 - 【内存空间初始化】初始化为
零值
。 - 【对象头初始化】把包括
对象是哪个类的实例
、如何找到类的元数据信息
、对象哈希码
、对象的GC年代
等信息保存到对象头中。 - 【执行init方法】根据对象初始化构造参数,调用相应的
<init>
方法,把字段设为需要的值(而非零值)。
##分配内存的细节 在分配的过程中,我们再来讨论下2. 内存分配
的细节。
###分配方法分类
笼统来说,内存分配方式可以分两种:
指针碰撞(Bump the Pointer)。 这种方式可以理解成把所有内存都当成一个整体,中间用一个指针摆在中间,左边全是用过的内存,右边全是没用过的内存,需要用的指定大小的内存时,左移分配内存。使用这种分配方式垃圾收集器包括:
Serial
、ParNew
等。空闲列表(Free List)。内存被分为一块块的空间,通过一个单独的列表来记录内存中哪些内存块空闲,哪些已被使用。使用这种肥配方是的垃圾收集器包括
CMS
等。
###分配时的线程安全
由于这里讨论的堆内存
是被多线程中共享的,所以在并发的过程中必须考虑线程安全问题。同样也有两种方案:
- 同步。同步控制每一个内存分配动作。
- Thread Local Allocation Buffer, TLAB。为不同线程划分特定的内存空间,一般情况下线程只在自己的分配空间内操作,只有TLAB空间用完才同步锁定,进行新的全局分配。
#布局
对象在内存中存储的布局分为三块
对象头
存储对象自身的运行时数据:Mark Word
(在32bit和64bit虚拟机上长度分别为32bit和64bit),包含如下信息:
- 对象hashCode
- 对象GC分代年龄
- 锁状态标志(轻量级锁、重量级锁)
- 线程持有的锁(轻量级锁、重量级锁)
- 偏向锁相关:偏向锁、自旋锁、轻量级锁以及其他的一些锁优化策略是JDK1.6加入的,这些优化使得Synchronized的性能与ReentrantLock的性能持平,在Synchronized可以满足要求的情况下,优先使用Synchronized,除非是使用一些ReentrantLock独有的功能,例如指定时间等待等。
- 类型指针:对象指向类元数据的指针(32bit-->32bit,64bit-->64bit(未开启压缩指针),32bit(开启压缩指针))
- JVM通过这个指针来确定这个对象是哪个类的实例(根据对象确定其Class的指针)
##实例数据
对象真正存储的有效信息
##对齐填充
JVM要求对象的大小必须是8的整数倍,若不是,需要补位对齐
Tips——对象起始地址必须是8字节的整倍数,即对象大小必须是8字节的整倍数。
访问
Java虚拟机规范中指定了虚拟机要访问对象的时候是通过Java虚拟机栈中的reference来获取对象地址的。但是并没有指定reference如何保存以及通过它具体如何获取对象地址。所以各家有各家的实现方案。
主要分两种,一种是通过句柄(保存在Java堆特定的句柄池中)间接访问,一种是直接在虚拟机栈中保存对象地址直接访问。HotSpot使用后一种方案。
转载于:https://my.oschina.net/djzhu/blog/993928
JVM hotspot虚拟机对象探秘相关推荐
- Hotspot虚拟机对象探秘
Hotspot虚拟机对象探秘 对象的创建 java 中提供的几种对象创建方式: 对象的创建主要流程 为对象分配内存 处理并发安全问题 对象的访问定位 句柄访问 直接指针 对象的创建 java 中提供的 ...
- JVM-02内存区域与内存溢出异常(中)【hotspot虚拟机对象】
文章目录 思维导图 对象的创建 对象的内存布局 实例数据(Instance Data) 对齐填充(Padding) 对象的访问定位 使用句柄(类似间接指针) 直接指针访问 (HotSpot采用这种方式 ...
- JVM中的对象探秘(三)- 对象的实例数据与对齐填充
引言 上一篇文章我们讲解了JVM对象内存布局的第一部分对象头,今天我们继续来讲讲剩下的两部分实例数据(Instance Data) .对齐填充(Padding). 实例数据与对齐填充 这两部分我们放在 ...
- JVM Hotspot 虚拟机与 DalvikART 虚拟机堆栈的区别
文章目录 Hotspot 虚拟机与 Dalvik 虚拟机的区别 Android 内存管理模型 JVM 与 Dalvik 虚拟机在栈的区别 AOT(Ahead Of Time)预先编译机制 JVM 与 ...
- 深入理解Java虚拟机(二)——HotSpot虚拟机对象
一.对象的创建 1.检查 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载.解析和初始化过.如果没有,那必须先执 ...
- HotSpot虚拟机对象的创建过程
1.文中讨论的对象限于普通Java对象,不包括数组和class对象. 2.内存的分配方式由Java堆是否规整来决定,而Java堆是否规整取决于垃圾收集器是否有压缩整理的功能. 3.还需要考虑:对象的创 ...
- Java JVM 从虚拟机的角度看对象的创建与访问
专栏原创出处:github-源笔记文件 ,github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明. Java JVM-虚拟机专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Java ...
- Java虚拟机对象的探索—对象的内存布局
在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 对象头(Header) HotSpo ...
- 【深入Java虚拟机JVM 05】HotSpot对象探秘
说明:文章所有内容均摘自<深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)> 介绍完Java虚拟机的运行时数据区之后,我们大致知道了虚拟机内存的概况,读者了解了内存中放了些什么后 ...
最新文章
- thinkphp 5.0.3 rce getshell_关于ThinkPHP的一些渗透方式
- 三款云数据库性能测试,谁表现最好?
- 个人站点提高访问量七大方案
- MySQL中间件之ProxySQL(13):ProxySQL集群
- Qracle学习:初识oracle
- 两个条件一个为false就运行_Python入门基础实例讲解——两个数字比大小,并输出最大值...
- Django的自带认证系统——auth模块
- 乐观锁的颗粒度_MySql数据库锁机制详解
- jquery 树形框 横_利用jQuery设计横/纵向菜单
- 计算机组成原理第二版知识大纲
- mysql的半同步复制
- python之路 《四》 字典
- 下载应用 ipa 包,不妨试试这款开源工具
- 基于Javaweb的图书馆管理系统设计与实现(开题报告+论文).doc
- 银行卡卡号归属地汇总
- 图片不能承受之重-转
- 风水大师 or 企业医生?张明明谈数据分析师的职业之路
- linux 深入理解I2C内核驱动
- MAC使用 SVN问题
- JavaScript图片轮播图
热门文章
- 2 Python 介绍
- 致我测试之路的“七年之痒”
- C# Check is No number
- VC程序调试技术,一些工具上和具体的问题,包括内存检测
- docker修改容器映射的端口_解密 Docker 挂载文件,宿主机修改后容器里文件没有修改...
- linux oracle 运维_Oracle查询当前的crs/has自启动状态实例教程
- GoogLeNet系列解读
- 整数划分问题的递归算法-c语言,简单的整数划分问题(递归)
- html path属性,HTML Location pathname用法及代码示例
- if test 多条件_if函数进阶篇 嵌套+多条件判断