JVM类加载之创建对象的过程
JVM对象的创建
new一个对象到底发生了什么?
1.VM遇到new关键字:首先检查是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否被加载,验证,准备,解析,初始化过,如果没有,必须先执行相应的类加载过程
2.类加载检查通过后,VM为新生对象分配内存,对象所需的内存空间大小在类加载完成之后便可确定,VM采用指针碰撞(内存规整:Serial,ParNew等有内存压缩功能的收集器)或空闲列表(内存不规整:CMS)的方式将一块确定大小的内存从java堆中划分出来。
指针碰撞:假设java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边。中间放着一个指针作为分界点的指示器,那所分配的内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离。
空闲列表:如果java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错。虚拟机必须维护一个列表,记录那些内存块是可用的,在分配的时候从列表中找到一块足够大的内存划分给对象实例,并更新列表上的记录。
3.由于VM创建对象的行为非常频繁,因此需要考虑内存分配的并发问题解决方案:
(1)对分配内存空间的动作进行同步:用CAS失败重试的方式
(2)把内存分配的动作按照线程划分在不同的空间中进行,每个线程在java堆中预先分配一小块内存,即本地线程分配缓冲TLAB,各线程首先在TLAB上分配内存,TLAB使用完之后,分配新的TLAB时才需要同步锁定。jvm是否使用TLAB可以通过-XX:+/-UseTLAB参数指定。
4.内存分配完成之后,VM需要将分配的内存空间都初始化为零(不包括对象头),如果在TLAB上分配内存,此过程可提前至TLAB分配时进行。这一步保证了对象的实例字段可以不赋初值也可以直接使用。
5.设置对象头信息;这些信息包括该对象是那个类的实例,如何才能找到该类的元数据信息,对象的哈希码,对象的GC分代信息等
6.对于VM来说,新的对象已经创建完成;但对于java程序来说,对象创建才刚开始,因为方法还没有执行,所有的字段都还为零,所以要执行方法进行初始化。
对象在内存中是怎样存在的?
在HotSpot Vm中,对象在内存中分为三个区域:对象头,实例数据和对其填充。
对象头
对象头包括两部分:类型指针Class Metadata Address和MarkWord。
类型指针即指向它的类元数据的指针,虚拟机可以通过类型指针确定该对象属于哪个类。
MarkWord用来存储对象本身的运行时数据:哈希码,GC分代年龄,锁状态标志,线程状态标志等。这部分数据的长度在32位和64位VM分别为32bit和64bit,称之为“Mark Word”。
实例数据
存储了程序中的各种类型的字段数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度。
对齐填充
不是必需存在的,为了字节填充,仅起到占位符的作用。
怎样能准确的找到内存中的对象--对象定位
Java程序通过虚拟机栈的局部变量表中的reference来找到堆中的对象,reference可以是指向对象的直接指针,也可以是指向句柄的指针。
(1)句柄:Java堆中将会划分出一块内存作为句柄池,reference中存储对象的句柄地址,而句柄中包含了对象实例数据与类型数据的具体各自的地址信息。
(2)直接指针:reference中存储的直接就是对象地址
JVM类加载之创建对象的过程的更多相关文章
- 搞懂JVM类加载机制
有这样一道面试题: class Singleton{ private static Singleton singleton = new Singleton(); public static int v ...
- JVM类加载过程学习总结
JVM类加载过程学习总结 先不说JVM类加载的原理,先看实例: NormalTest类,包含了一个静态代码块,执行的任务就是打印一句话. /** * 在正常类加载条件下,看静态代码块是否会执行 * @ ...
- 【深入Java虚拟机】一 JVM类加载过程
首先Throws(抛出)几个自己学习过程中一直疑惑的问题: 1.什么是类加载?什么时候进行类加载? 2.什么是类初始化?什么时候进行类初始化? 3.什么时候会为变量分配内存? 4.什么时候会为变量赋默 ...
- JVM类加载过程详细分析
双亲委派加载模型 为什么需要双亲委派加载模型 主要是为了安全,避免用户恶意加载破坏JVM正常运行的字节码文件,比如说加载一个自己写的java.util.HashMap.class.这样就有可能造成包冲 ...
- JVM -- 类加载的过程
类的加载过程? 一个Java文件从编码完成到最终执行,一般主要包括"编译"和"运行"两个过程.编译,即把我们写好的java文件,通过javac命令编译成字节码, ...
- 不止面试—jvm类加载面试题详解
面试题 带着问题学习是最高效的,本次我们将尝试回答以下问题: 什么是类的加载? 哪些情况会触发类的加载? 讲一下JVM加载一个类的过程 什么时候会为变量分配内存? JVM的类加载机制是什么? 双亲委派 ...
- java类加载、对象创建过程
类加载过程: 1, JVM会先去方法区中找有没有相应类的.class存在.如果有,就直接使用:如果没有,则把相关类的.class加载到方法区 2, 在.class加载到方法区时,会分为两部分加载:先加 ...
- JVM加载类的过程,双亲委派机制中的方法
JVM加载类的过程: 1)JVM中类的整个生命周期: 加载=>验证=>准备=>解析=>初始化=>使用=>卸载 1.1.加载 类的加载阶段,主要是获取定义此类的二进 ...
- JVM类加载续
上一篇理解了JVM类加载过程的第一个阶段,这篇来说说剩下的阶段:验证.准备.解析.初始化.需要注意的是,这些阶段(解析除外)只是按照这个顺序开始,但是执行的过程中可能存在交叉. 验证:就是要对加载的二 ...
随机推荐
- 【LeetCode】259 3Sum Smaller
题目: Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 ...
- poj3468区间加减查找——树状数组区间修改查询
题目:http://poj.org/problem?id=3468 增加一个更改量数组,施以差值用法则区间修改变为单位置修改: 利用公式可通过树状数组维护两个数组:f与g而直接求出区间和. 代码如下: ...
- rmmod: chdir(/lib/modules): No such file or directory
内核版本:linux3.4.20 交叉编译器:arm-linux-gcc 4.3.3 busybox : busybox 1.20 问题: 使用rmmod会出现 rmmod : chdir(/lib ...
- Eclipse常用配置(1)
1.代码自动提示 在我们忘记方法名或者想偷懒时,代码自动提示很管用.不过Eclipse默认是输入"."后才会出现包或类成员的提示,也就意味着我们必须先输入一个完整的类名,提示才能出 ...
- 导出数据到EXCEL并生成多个Sheet
一.准备工作 引用:Microsoft.Office.Interop.Excel 准备多个DataTable数据添加到DataSet中. 二.代码 public void CreateExcel(Da ...
- 第3章 编写ROS程序-2
1.发布者程序 在本节中,我们将看到如何发送随机生成的速度指令到一个turtlesim海龟,使它漫无目的地巡游.这个程序的源文件称为pubvel,这个程序展示了从代码中发布消息涉及的所有要素. 其代码 ...
- 优酷电视剧爬虫代码实现一:下载解析视频网站页面(4)补充: Java正则表达式Matcher.group(int group)相关类解析
在Java正则表达式的相关类Matcher中,有如下几个方法: - int groupCount() - String group(int group) - int start(int group) ...
- freemaker宏的用法
freemaker宏 定义:定义一个标签,标签体中可以包含参数,开始标签和结束标签可以包含内容,内容中可以通过${}方式引用标签体中定义的参数 用法:页面引入标签,通过标签可以直接输出标签的内容 He ...
- CentOS6下用yum升级系统最新内核版本
首先当你决定升级内核时,要想清楚为什么升级内核,因为升级内核会带来很多麻烦.所以这种事情能避免就避免 导入 Public Key rpm --import https://www.elrepo.org ...
- elasticsearch学习(三):分布式
es的分布式思想跟现在流行的很多开发技术的分布式一个道理.一个es 搜索服务作为一个集群,集群中存在很多节点,一个节点就是一个搜索服务器.这么多节点中,会按照一定的机制推举出一个 master节点,该 ...