java虚拟机(三)--HotSpot 对象
普通对象的创建(不包括数组和class对象):
当虚拟机遇到new指令时,会在常量池中检查是否包含这个类的符号引用(全限定名),通过这个确定是否经过类加载的过程,如果true,为该
对象分配内存,对象大小在类加载过程就已经确定。如果false,需要进行类加载。
分配内存
1、分配内存的方式:
指针碰撞:如果内存是绝对规整的,使用过的在一边,未使用过的在另一边,中间有个指针作为分界点的指示器,为对象分配内存的时候,只需
要向未使用过的一边移动与对象大小相同的距离完成内存分配
空闲列表:内存非规整的情况下,jvm通过维护一个列表记录哪些内存可用,在分配内存的时候,从列表里面找到一个大于对象大小的内存进行
分配,并且更新列表记录使用哪种内存分配方式取决于使用哪种垃圾收集器:
Serial、ParNew等带有Compact过程,采用指针碰撞
类似CMS这种基于Mark-Sweep算法的收集器,采用空闲列表
2、并发环境下分配内存:
如果给对象A分配内存的时候,指针还没来及修改,对象B使用原来的指针来分配内存(类似脏读)
解决方案:
①.对分配内存的动作进行同步处理--通过CAS+失败重试的方式保证操作的原子性(了解CAS机制可以查看Atomic源码)
②.使用本地线程缓冲区TLAB,就是为每个线程在堆中预先分配一小块内存,各个线程分配内存相互不影响(类似ThreadLocal变量概念),只
有在TLAB用完重新分配新的TLAB时,才需要进行同步处理。通过-XX:+/-UseTLAB参数配置是否使用TLAB
上述分配内存动作完成。
初始化内存
此时,jvm将分配的内存空间初始化为零值(不包含对象头),如果使用TLAB,在分配TLAB时提前完成这一步
作用:
为了保证用户没有赋初值的情况下也是可以使用
然后设置对象头保存的一些信息,例如:这个对象是哪个类的实例,如何找到类的元数据信息、对象的哈希码、GC分代年龄等。
都完成之后,VM角度来看,一个对象已经产生,但程序的角度,对象创建才刚开始——<init>方法还没执行,所有字段都是零值,初始化过程,
一个真正的对象才完成
对象的内存布局(HotSpot)
1、对象头Header:
①存储对象本身的运行时数据,如hashcode,GC分代年龄、锁状态标志、线程持有的锁等
②类型指针:对象指向本身类元数据的指针,虚拟机就是通过类型指针确定对象是哪个类的实例。但不是所有的对象都保存类型指针,所以查
找类的元数据也不一定通过对象本身
针对数组,Header还要一个记录数组长度的数据,因此无法通过数组的元数据确定数组大小,但是普通java对象是可以的
2、实例数据Instance Data:
对象真正存储的有效数据,也就是代码定义的各种类型字段,无论是从父类继承的,还是子类本身定义的。相同宽度的字段被分配到一起。满
足这个条件前提下,父类定义到子类前,但是如果CompactFields=true,子类较小的变量也可能插入到父类变量的空隙
3、对齐填充Padding:
不是必然存在的,没有特别的意义,起着占位符的作用,对象起始地址要是8字节的整数倍,就是对象的大小必须是8字节的整数倍,对象头是8
字节的1倍或2倍,当对象实例数据部分没有对齐时,需要对齐填充来补全。
对象的访问定位
java程序通过栈中的reference操作堆中的具体数据。
定位方式:
①.句柄访问(间接):堆中维护一个句柄池,本地变量表中reference存储的就是对象的句柄地址,句柄池包含了对象实例数据(堆)和类型数
据(方法区)各自的地址信息

②.直接指针访问:reference中存储的就是对象实例数据,实例数据有指向方法区中的对象类型数据的指针

对比:
句柄访问的优点:reference中保存的只是句柄地址,如果对象GC被移动只需要改变实例数据指针,reference本身不需要改变
指针访问的优点:速度更快。节省一次指针定位的时间开销,因为对象访问在java很频繁,所以节省的时间开销是很客观的。HotSpot采用指针访问
java虚拟机(三)--HotSpot 对象的更多相关文章
- 深入理解Java虚拟机(二)——HotSpot对象创建、内存、访问
对象的创建 虚拟机遇到一条字节码new指令时,开始对象创建过程. 首先去检查这个指令的参数是否能在常量池定位到一个类的符号引用: 检查这个符号引用代表的类是否已被加载.解析和初始化,如果没有就必须执行 ...
- Java虚拟机三:OutOfMemoryError异常分析
根据Java虚拟机规范,虚拟机内存中除过程序计数器之外的运行时数据区域都会发生OutOfMemoryError(OOM),本文将通过实际例子验证分析各个数据区域OOM的情况.为了更贴近生产,本次所有例 ...
- 深入理解java虚拟机(三)-----类加载机制
类加载机制jvm把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被jvm直接使用的java类型.在java中,类型的加载.连接和初始化都是在程序运行期间完成的 ...
- 深入理解Java虚拟机(三)——垃圾回收策略
所谓垃圾收集器的作用就是回收内存空间中不需要了的内容,需要解决的问题是回收哪些数据,什么时候回收,怎么回收. Java虚拟机的内存分为五个部分:程序计数器.虚拟机栈.本地方法栈.堆和方法区. 其中程序 ...
- 深入理解Java虚拟机(四)——HotSpot垃圾收集器详解
垃圾收集器 新生代收集器 1.Serial收集器 特点: 单线程工作,收集的时候就会停止其他所有工作线程,用户不可知不可控,会使得用户界面出现停顿. 简单高效,是所有收集器中额外内存消耗最少的. 没有 ...
- Java虚拟机三 Java堆和栈
Java堆是和Java应用程序关系最为紧密的内存空间,几乎所有的对象都存放在堆中.并且堆是完全自动化管理的. 根据垃圾回收机制的不同,Java堆有可能有不同的结构.最为常见的一种就是将整个Java堆分 ...
- 虚拟机性能监控与故障处理工具(深入理解java虚拟机三)
JDK自带的工具可以方便的帮助我们处理一些问题,包括查看JVM参数,分析内存变化,查看内存区域,查看线程等信息. 我们熟悉的有java.exe,javac.exe,javap.exe(偶尔用),jps ...
- 深入理解Java虚拟机(三)、垃圾收集算法
1.第一门真正使用内存动态分配和垃圾收集技术的语言:Lisp 2.程序计数器.虚拟机栈.本地方法栈这3个区域随线程而生灭,这几个区域的内存会随着方法结束或线程结束而回收,GC关注的是Java堆和方法区 ...
- 基于Java的三种对象持久化方式
1:序列化技术: 序列化的过程就是将对象写入字节流和从字节流中读取对象.将对象状态转换成字节流之后,可以用java.io包中的各种字节流类将其保存到文件中,可以通过管道或线程读取,或通过网络连接将对象 ...
随机推荐
- hdu1078 FatMouse and Cheese(记忆化搜索)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1078 题目大意: 题目中的k表示横向或者竖直最多可曾经进的距离,不可以拐弯.老鼠的出发点是(1,1) ...
- core.async中go的作用研究
(defmacro go "Asynchronously executes the body, returning immediately to the calling thread. Ad ...
- VMware 虚拟机下挂载U盘
1.首先设置虚拟机为连接的可移动U盘 2.首先在虚拟机界面的情况下,插入U盘,U盘格式为fat32的 3.在mnt目录下新建一个文件夹usb 4.运用sudo fdisk -l /dev/sdb 来查 ...
- vue 目录结构介绍
1 初始目录如下: 2 目录结构介绍 bulid:最终帆布的代码存放位置 config:配置目录,包括端口号等 node_modules:npm加载的项目依赖模块 src:z这里是我们要开发的目录,基 ...
- ViewModel、ViewData、ViewBag、TempData、Session之间的区别和各自的使用方法
ViewModel ViewModel 是一个用来渲染 ASP.NET MVC 视图的强类型类,可用来传递来自一个或多个视图模型(即类)或数据表的数据.可将其看做一座连接着模型.数据和视图的桥梁 ...
- bzoj 1026: [SCOI2009]windy数【数位dp】
忘记limit不能记WA了一发-- 典型数位dp,变成work(r)-work(l-1),然后dfs的时候记录w当前位置,la上一个数选的什么,lm当前位是否有上限,ok当前位是否可以不考虑差大于等于 ...
- poj 2409 Let it Bead【polya定理+burnside引理】
两种置换 旋转:有n种,分别是旋转1个2个--n个,旋转i的循环节数位gcd(i,n) 翻转:分奇偶,对于奇数个,只有一个珠子对一条边的中点,循环节数为n/2+1:对于偶数个,有珠子对珠子和边对边,循 ...
- 微信扫码下载APK遮罩提示示例
由于微信的限制,应用文件在内置浏览器中下载全部被屏蔽掉,造成很多人用微信扫描二维码下载时,界面显示一片空白,容易误导以为在下载呢.按照当前主流习惯,做一个提示用户在浏览器中打开下载的遮罩.网上很多现成 ...
- [Qt Creator 快速入门] 第1章 Qt Creator简介
Qt Creator 是一个跨平台的.完整的 Qt 集成开发环境,其中包括了高级C++代码编辑器.项目和生成管理工具.集成的上下文相关的帮助系统.图形化调试器.代码管理和浏览工具等.这一章先对 Qt ...
- GIT学习之路最终日 标签管理+总结
本文参考廖雪峰老师的博客进行总结,完整学习请转廖雪峰博客 6.1 创建标签 命令git tag (name)用于新建一个标签,默认为HEAD,也可以指定一个commit id: git tag -a ...