
文章插图
假期结束了,勾勾18号就开始上班,已经开始忙碌,最近更新也比较少了 。
在开始MySQL的学习之前,还想写一篇文章把前面学习的知识点回顾一下,就有了今天的这篇文章 。
示例
有类School,这个类中有3个成员变量:引用类型String类型的schoolName,通过显式代码块初始化;基本数据类型int型studentsNum,显式初始化;引用类型Class类型student,通过School的构造函数初始化 。
我们使用main函数创建School的一个对象,那么这个过程发生了哪些事情?在JVM内存中多了什么呢?让我们一起看下吧!
publicclassSchool{privateStringschoolName;privateintstudentsNum=10000;privateStudentstudent;{schoolName="清华大学";}publicSchool(){student=newStudent();}}classStudent{}classTest{publicstaticvoidmain(String[]args){Schoolschool=newSchool();}}
当我们执行new School()时,进行了对象的创建,大致可以分为以下5步:

文章插图
在详细了解这5个步骤之前我们再详细聊一下对象头,在synchronized锁升级过程分析的时候我们已经初步接触过它 。
对象的内存布局
对象在堆空间的内存布局包含了3个部分:对象头(Header)、实例数据(Intance Data)、对齐填充(Padding) 。
对象头
对象头包含了两部分:运行时元数据、指向类元数据的指针kclass,确认这个对象所属的类型 。

文章插图
运行时元数据(Mark Word)包含:哈希值、GC分代年龄、锁状态标志位、偏向线程ID 。运行时元数据的信息是变化的,在synchronized锁的升级过程中,Mark Word在不同的锁状态下是不一样的 。
下图展示展示了无锁状态、偏向锁、轻量级锁、重量锁以及对象被GC标记的对象头中的运行时数据信息:

文章插图
实例数据
实例数据是对象真正存储的有效信息,它包含了对象中定义的各种类型的字段 。这些字段有对象本身定义的,也有从所有父对象继承的字段 。
父类的构造方法先于子类执行,所以父类变量的定义都在子类前面 。
对齐填充
对齐填充不是必须的,也没有实在的意义,它仅仅是个占位符的作用 。HotSpot虚拟机要求对象的起始地址必须是8字节的整数倍,因此当对象没有满足的时候,就需要对齐填充来补全 。
现在我们已经了解了对象在堆内存的布局,在之前的JVM文章中也学习了虚拟机栈结构和方法区(JDK1.8之后称为元空间,勾勾之前习惯称为方法区,但是怕大家混淆后续我们都用元空间表示),那么接下来我们详细分析school对象创建的整个过程 。
对象创建的步骤
对象的创建是在主线程的main()方法中,所以在主线程的虚拟机栈中就会创建main()的栈帧,main()就是当前方法 。
我们回顾下栈和栈帧 。
JVM内存区域划分为5个模块:堆、元空间、虚拟机栈、本地方法栈和程序计数器(也成为pc寄存器) 。
虚拟机栈和本地方法栈都属于栈,本地方法栈中只存放native方法的栈信息 。
虚拟机栈的生命周期和线程的生命周期一致,它随着线程的创建而创建,随着线程的销毁而销毁,所以它是线程私有的内存区域 。
虚拟机栈是由栈帧组成的,栈帧中包含了局部变量表、操作数栈、动态链接、方法返回地址、附加信息 。栈帧是随着方法的调用而创建的 。所以当主线程调用main()方法时,此时在主线程的虚拟机栈中就创建了main()栈帧 。
推荐阅读
- 在人类身上也有堪比猛兽的攻击性部位?实战起来能吓自己一跳
- 风池穴有7大作用 风池穴
- 客家娘酒用什么做的,梅州客家娘酒的做法
- 干股出资计算 干股占股比例怎么算
- 怎么瘦手臂最有效的方法 如何瘦手臂
- 天天拉手指会变修长吗 如何瘦手指
- 如何瘦腰瘦肚子最快最有效的运动 如何瘦手
- 怎样才能瘦腿最快最有效 如何瘦成筷子腿
- 男生瘦翘臀的运动 如何瘦屁股和翘臀
