Java对象的创建 —— new之后JVM都做了什么?
Java对象创建过程
1. 类加载检查
虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化过。如果没有则进行相应的类加载过程。(我之后会写一篇关于类加载顺序和过程的博客,并在此补充连接地址)
2. 分配内存空间
类加载检查通过之后,JVM将为新生对象在堆中分配内存。对象所需内存的大小在类加载完成后已经完全确定了(一个Java对象到底占用多大内存)。为对象分配空间就相当于在Java堆上将一块确定大小的空间划分出来。如果Java堆是连续分配的,一边是存储了对象的,另一边是空闲的,中间放着一个指针作为分界点的指示器,则为对象分配空间只需要将指针想空闲的一边移动对象大小的位置即可。这种方式叫做“指针碰撞”(bump the pointer)。如果Java堆不是连续分配的,虚拟机就需要维护一个列表记录每一个已经分配的对象和没有分配的对空间信息。当需要分配空间时,找出一个足够大的空闲空间分配给新生对象然后更新列表上的记录,这种方式被称为“空闲列表”(Free List)。
选择哪种分配方式是由Java堆是否连续规整决定的,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。因此,在使用Serial, ParNew等带Compact过程的收集器时,系统采用的是指针碰撞,而使用CMS这种基于Mark-Sweep算法的收集器时,通常采用的是空闲列表。
3. 设置对象基本信息
对象分配到空间之后,JVM会将分配到的内存空间都初始化为零值(不包括对象头)。之所以不对对象头做初始化零值设置,是因为虚拟机要对对象进行必要的基本信息设置。如该对象是哪个类的实例、如果找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头中,被叫做“Mark Word”。(Java对象的内存布局以及对象所需内存大小计算详解)
4. 程序员意愿的初始化与调用构造函数
以上工作都做完之后,对JVM来说,一个对象已经创建完毕。但是从Java程序的视角来说,对象创建才刚刚开始:首先程序会按照程序员的定义来初始化对象(如定义了成员变量 private int age = 10,此时会设置age的值为10),这样一个真正可用对象才算完全产生出来。然后程序会调用构造方法。到此为止,一个对象才算完全完成了创建和初始化的工作,可以使用了。
例子
public class InitDemo {
private int age = 10;
public InitDemo() {
System.out.println("before: " + age);
age = 20;
System.out.println("after: " + age);
}
public static void main(String[] args) {
InitDemo demo = new InitDemo();
/**输出结果:
before: 10
after: 20
*/
}
}
}
声明:文章内容是对《深入理解Java虚拟机——JVM高级特性与最佳实现》第二版相关章节学习的总结。
Java对象的创建 —— new之后JVM都做了什么?的更多相关文章
- 图解JAVA对象的创建过程
前面几篇博文分别介绍了JAVA的Class文件格式.JVM的类加载机制和JVM的内存模型,这里就索性把java对象的创建过程一并说完,这样java对象的整个创建过程就基本上说明白了(当然你要有基础才能 ...
- 深入理解Java对象的创建过程:类的初始化与实例化
摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...
- (转)深入理解Java对象的创建过程
参考来源:http://blog.csdn.net/justloveyou_/article/details/72466416 摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一 ...
- Java对象的创建过程:类的初始化与实例化
一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...
- Java对象的创建及使用
Java对象的创建及使用 对象是类的具体实例(instance),是真实存在的个体:
- [转帖]支撑双11每秒17.5万单事务 阿里巴巴对JVM都做了些什么?
支撑双11每秒17.5万单事务 阿里巴巴对JVM都做了些什么? https://mp.weixin.qq.com/s?__biz=MzA3OTg5NjcyMg==&mid=2661671930 ...
- 【深入理解JVM】:Java对象的创建、内存布局、访问定位
对象的创建 一个简单的创建对象语句Clazz instance = new Clazz();包含的主要过程包括了类加载检查.对象分配内存.并发处理.内存空间初始化.对象设置.执行ini方法等. 主要流 ...
- Java对象的创建
学了很久的java,是时候来一波深入思考了.比如:对象是如何在JVM中创建,并且被使用的.本文主要讲解下new对象的创建过程.要想更深入的了解建议去认认真真的看几遍<深入理解Java虚拟机> ...
- Java对象的创建、内存布局和访问定位
在Java运行时数据区中,我们知道了虚拟机内存的概况,本文介绍虚拟机内存中的数据的其它细节,如对象如何创建.如何布局以及如何访问. 基于实用的原则,这里以HotSpot虚拟机和常用的内存区域Java堆 ...
随机推荐
- netcore webapi帮助文档设置
如何建 .netcore webapi 项目这个就不说了,这个都没有没必要看下去. 我这里是.netcore 2.0,虽然没测过1.0的,但想来差不多. 1.Nuget Packages安装,使用程序 ...
- 在vue项目中, mock数据
1. 在根目录下创建 test 目录, 用来存放模拟的 json 数据, 在 test 目录下创建模拟的数据 data.json 文件 2.在build目录下的 dev-server.js的文件作如下 ...
- SQL to Java code for Elasticsearch
Elasticsearch虽然定位为Search Engine,但是因其可以持久化数据,很多时候,我们把Elasticsearch当成Database用,但是Elasticsearch不支持SQL,就 ...
- 高并发下,log4j日志打印行数导致的内存溢出问题
log4j日志打印时,如果将行数打印出来,在调用量极大的情况下,会出现内存溢出问题. log4j打印日志,打印行数时,行数是通过一个一个exception抛出,再极高调用量的情况下,内存会因为exce ...
- [LeetCode] Valid Triangle Number 合法的三角形个数
Given an array consists of non-negative integers, your task is to count the number of triplets chose ...
- 3.如何搭建Appium自动化测试环境
整个APP自动化环境安装可以参照虫师博客安装 附以下链接: http://www.cnblogs.com/fnng/category/695788.html 下面介绍运用到工作中遇到的一些问题 1.如 ...
- Linux服务器断电导致挂载及xfs文件损坏的修复方法
系统文件损坏后进入紧急修复模式,无法进行维护工作 welcome to emergency mode!after logging in ,type "journalctl -xb" ...
- 十大面试难题解惑,看完秒杀一切 HR 面。程序员必读!
最能体现求职者能力的就是面试,能不能拿到Offer,取决于你面试时的表现,只有有准备才能在面试过程中游刃有余. 小编收集了10个面试官最爱提的问题,虽然题目千变万化,但是万变不离其宗,只要掌握了答题的 ...
- NOI2006 郁闷的出纳员
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- ●BZOJ 4541 [Hnoi2016]矿区
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4541 题解: 平面图的对偶图,dfs树 平面图的对偶图的求法: 把所有双向边拆为两条互为反向 ...