要看的懂对象的创建过程,首先你得有对Java虚拟机和Java基础以及JUC很是熟悉,比如类的加载过程,CAS、多线程、JVM的GC等等

首先好看一个图,我大概会根据图中的内容来分享这六个步骤(其实几个步骤不重要,只要包括的内容都在就行):

一、以下是创建对象的六个步骤:

1、判断是否能在常量池中能找到类符号引用,并检查是否已被加载、解析、初始化(即判断类元信息是否存在)

如果没有则在双亲委派模式下,使用当前类加载器以ClassLoader + 包名 + 类名为Key进行查找对应的.class文件以此来完成类的加载进内存。在这个过程中,要是找不到要加载的类JVM就会抛出ClassNotFoundException异常,意思就是找不到该类进行加载。

2、为对象分配内存空间

首先计算对象占用空间大小,接着在堆中划分一块内存给新对象,如果实例成员变量是引用变量,仅分配引用变量空间即可,即4个字节。文章结束附有Java八种基本数据类型的所占字节数,分配内存时根据堆中内存是否规则分为:

① 内存规整—指针碰撞:如果是规整的,那么虚拟机将采用指针碰撞法来为对象分配内存。

意思就是所有用过的内存在一边,空闲的内存在另一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针向空闲那一边挪动一段与对象大小相等的距离,以此来分配内存给对象。如果垃圾收集器选择的是Serial、ParNew这种基于标记压缩算法的,也就是一般使用带有compact(整理)过程的收集器时,就会使用指针碰撞分配方法。

② 内存不规整—空闲列表:如果内存不是规整的,已使用的内存和未使用的内存相互交错,那么虚拟机将采用这种空闲列表法给对象分配内存。

意思就是虚拟机维护了一个列表,记录上哪些内存块是可用的,再分配的时候从列表找到一块足够大的空间划分给对象实例,这种分配方式就是空闲列表(Free List)。

3、处理并发问题

为什么会有这个阶段呢?就是我们都知道堆空间是多个线程共享的,那么多个线程同时去操作堆空间数据时就会存在并发线程安全问题。

两种方式去解决这种并发安全问题:

① 采用CAS失败重试、区域加锁更新的原子性。

CAS算法是这样的:CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用到的技术,Java并发包(Java.Util.Concurrent)中的很多类都使用了CAS技术。

CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。

CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。

大白话:假如A线程要把共享变量sum的值从1修改为2,那么这时候A线程会先通过地址去获取一次sum的初始值1作为预期值,在修改之前会把之前获取的预期值与当前sum的值进行一次比较,假如两个值相同,那就将1修改为2,如果在A线程修改之前,B线程进入把sum的值提前修改为0了,那么A线程在用预期值去与当前的sum值0比较,显然两个值不相等,此时的A线程的操作就会停止。

② 每个线程预先分配一块TLAB—通过-XX:+ /-UseTLAB参数来设定

TLAB这一块区域是在堆当中Eden(伊甸园)区中的,大概占整个Eden区的1%左右,很小的一块区域,堆为每一个线程单独分配一块TLAB,以此来保证多线程共享数据时是线程安全的。

4、初始化分配到的空间(对属性初始化,零值初始化)

这一过程说白了就是:所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用。基本数据类型默认初始化的值在文章下方表格里。

5、设置对象的对象头

将对象的所属类(即类的元数据信息)、对象的HashCode、对象的GC信息、锁信息等数据存储在对象头中。这个过程的具体设置方式取决于JVM实现。

6、执行init方法进行初始化

可以简单理解成调用构造函数进行显示的赋值,代码中和构造器中初始化。在Java程序的视角看来,初始化才正式开始,初始化成员变量,显示赋值,执行实例化代码块,调用类的构造器,并把堆内对象的首地址赋值给引用变量。

一般来说(由字节码中是否跟随有invokspecial 指令所决定), new指令之后会接着就是执行方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全创建出来。

扩展:还有一个clinit方法,这个方法是加载时对类中static静态修饰的属性和静态代码块进行初始化(此过程是在链接阶段的准备阶段)。这是JVM相关的知识了。

二、对象头的内部结构

1、创建了Customer()实例 和 Account()实例

2、对象头里包括:运行时元数据、类型指针、实例数据、对齐填充

① 运行时元数据里又包括:哈希值(HashCode)、GC分代年龄、锁状态标志

哈希值:它是一个地址,用于栈对堆空间中对象的引用指向,不然栈是无法找到堆中对象的

GC分代年龄:记录幸存者区对象被GC之后的年龄age,,一般age为15之后下一次GC就会直接进入老年代

锁状态标志:记录一些加锁的信息

② 类型指针:是对方法区中类元信息的引用

③ 实例数据:真实记录一个对象包含的数据,比如说一个person对象,里面可能包含年龄、性别、身高等等

其中数据为字符串的,要引用到字符串常量池。

想知道jdk8字符串常量池到底在那个地方存储的可以看这里。

④ 对其填充:这一区域就相当于一个快递在邮寄过程中,访问物品损坏,塞的一层填充物,起到一个缓冲的作用。

另外这个过程还会涉及到逃逸分析。我写了一篇逃逸分析的具体作用,感兴趣可以看看。

基本数据类型

所占字节数

默认值

包装类名称

byte

1(1字节=8位)

0

Byte

short

2

0

Short

int

4

0

Integer

long

8

0L

Long

double

8

0.0d

Double

float

4

0.0f

Float

char

2

‘\u0000’

Character

boolean

1

false

Boolean

怎样快速记住这些类型的方法,请看这里。

有用点个关注,手留余香!

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

java中修改对象类的数据_Java中创建对象的六个步骤 细分后(new关键字)对象头详细介绍...相关推荐

  1. Java中创建对象的六个步骤 细分后(new关键字)对象头详细介绍

    要看的懂对象的创建过程,首先你得有对Java虚拟机和Java基础以及JUC很是熟悉, 比如类的加载过程.CAS.多线程.JVM的GC等等 文章目录 一.创建对象的六个步骤: 二.对象头的内部结构 首先 ...

  2. java中的class 类的作用_Java中Class和单例类的作用与类成员的理解

    Java中Class类的作用与深入理解 在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识.这个信息跟踪着每个对象所属的类.JVM利用运行时信息选择相应的方法执行.而保存 ...

  3. java实例成员和类成员变量_Java 中成员变量又分为 和类成员变量。_学小易找答案...

    [简答题]I'm not quite so poetic, but I do know that the subway is as essential to the character of New ...

  4. java中怎么找类的路径_Java中获取类加载路径和项目根路径的5种方法

    public class MyUrlDemo { public static void main(String[] args) { MyUrlDemo muDemo = new MyUrlDemo() ...

  5. 在asp.net 2.0中使用SqlBulkCopy类迁移数据

    在asp.net 2.0中使用SqlBulkCopy类迁移数据 (转) http://jackyrong.cnblogs.com/archive/2005/08/29/225521.html 我们经常 ...

  6. 在asp.net 2.0中使用SqlBulkCopy类迁移数据[转]

    我们经常要在一个表中将数据迁移到另一个表,当然,用的方法十分多了.在.net 2.0中,提供了一个sqlbulkcopy类,也可以实现如下的操作,下面简单介绍下.比如一个表如下 CREATE TABL ...

  7. java怎样将多个list写入txt中并且不覆盖原有数据_java容器,面试必备知识点整理!...

    在码代码的过程中,我们常常需要对大量对象引用管理,为了有效的归类管理,将同类的引用放在一个数据容器中. 容器主要由:Collection与Map两种构成. 一.概述 1.Collection 包含三大 ...

  8. java中String类是什么_Java中字符串的学习(一)String类的概述及常见方法使用

    转载请注明出处http://www.cnblogs.com/devtrees/p/4347079.html (拓展:Api:编程语言对外给我们提供的应用程序接口.) 一.概述: 我们平时上网发帖,帖子 ...

  9. java实体类怎么写_Java中(entity)实体类的书写规范

    在日常的Java项目开发中,entity(实体类)是必不可少的,它们一般都有很多的属性,并有相应的setter和getter方法.entity(实体类)的作用一般是和数据表做映射.所以快速写出规范的e ...

  10. java中怎么使用json数据_JAVA中使用JSON进行数据传递

    1.是不是只有xml传递数据的技术才是webservice? 可以这么理解.webservice是基于SOAP协议,SOAP协议是基于XML的文本协议.所以webservice可以简单理解为是基于XM ...

最新文章

  1. 华人一作占半数,陶大程等人上榜,CVPR公布32篇最佳论文候选
  2. Android NDK JNI C++ 13 pthread多线程
  3. NodeJs 的几种文件路径
  4. flash与字符串:数组转换为字符串
  5. createrepo命令安装_安装CDH6.3
  6. vba读取csv文件到excel_利用VBA打开顺序文件,并读取
  7. 计算机与采集卡无法通信,通信工程毕业设计(论文)-基于.NET平台的高速图像采集.doc...
  8. Could not establish connection to hadoop0:10000/default: Connection refused: connect
  9. KMP算法详解 网络上转的。。。仰慕此人
  10. 等差数列末项计算(信息学奥赛一本通-T1035)
  11. 多出口冗余网络设计方案
  12. 破解技术人才招聘难、培养难!CSDN 软件工程师能力认证标准正式开源开放
  13. 解决maven打包打不进lib下的第三方jar包问题
  14. SpringMVC的json数据交互
  15. Python 进阶 —— 装饰器函数的使用
  16. [分享]Java 线程池的原理与实现
  17. 视频教程-webpack基础和完整项目脚手架搭建教程-JavaScript
  18. PostScript 打印描述语言 介绍
  19. 刷排名优优软件_QQ群排名技术原理
  20. linux 下面dev文件,Linux下目录的含义,例如lib中放置了什么文件,dev是什么

热门文章

  1. Eclipse无法查看Servlet源代码的解决方案
  2. python 函数篇(2)
  3. 【并查集】并查集专题总结
  4. ENVI 监督分类Max stdev from Mean 参数IDL中的设置
  5. 深圳信息职业技术学校 计算机辅助设计和制造,大学生职业生涯规划书样稿.doc...
  6. 拓端tecdat|R语言NLP案例:LDA主题文本挖掘优惠券推荐网站数据
  7. 拓端tecdat|用Python进行图像模糊处理和特征提取
  8. 数据系统 需要的服务器配置,数据系统 需要的服务器配置
  9. C语言模拟信号量解决同步、互斥问题
  10. 文本数据增强(data augmentation)textattack使用