uu聊天室如何_对象的创建过程
假期结束后,18号开始上班,已经很忙了,最近更新也很少。
在开始MySQL的学习之前,还想写一篇文章把前面学习的知识点回顾一下,就有了今天的这篇文章。
示例
有类School,这个类中有3个成员变量:引用类型String类型的schoolName,通过显式代码块初始化;基本数据类型int型studentsNum,显式初始化;引用类型Class类型student,通过School的构造函数初始化。
对象头
实例数据
对齐填充
现在我们已经了解了对象在堆内存的布局,在之前的JVM文章中也学习了虚拟机栈结构和方法区(JDK1.8之后称为元空间,勾勾之前习惯称为方法区,但是怕大家混淆后续我们都用元空间表示),那么接下来我们详细分析school对象创建的整个过程。
判断对象的类别是否已经加载
我们通过javapp-test.clast.clas查看Test类字节代码信息:
class ;/e:/study/javerl/main/com/study/cost/cost/girl/bsp;
研究生产中的标题;研究生产中的标题;研究生产中的标题;研究生产中的标题;研究生产中的标题;研究生产中的标题;研究生产中的标题;研究生产中的标题;研究生产中的标题;研究生产中的标题;研究生产中的标题如果没有这个类的信息,那么就会按照双亲委派模型加载School类。
类加载过程:加载、连接、初始化,其中连接包括验证、准备、分析。 执行类加载的是类加载器,分为启动类加载器、扩展类加载器、应用类加载器和定制加载器。 School类是ClassPath下的文件,其类别加载是应用类别加载器,应用类别加载器根据ClassLoader包名类别找到对应的.class文件时,如果找不到该文件,ClassNotFoundexception就会出现异常,如果找到了,就进行类别加载,生成对应的Class类别。此时,元空间有School的元数据。 针对分配内存空间
接下来需要计算对象所占空间的大小,基本类型除long和double外为8个字节,byte和boolean为1个字节,char和short为2个字节,其他基本类型为4个字节,uu聊天室如何引用类型也为4个字节。 内存大小计算后,在堆积中将内存空间划分为新对象。大部分情况下,对象是在新生代的Eden区中分配,如果此时Eden区没有足够的内存空间进行分配,虚拟机将发起一次Minor GC。但是,当我们将内存分配成长的文字串和数组时,这种类型的大对象需要连续的内存空间,可以直接分配给老年人,避免Eden和2个s区域发生大量的内存复制。但是大对象可能会导致连续空间不足而提前触发GC,我们开发中也应该尽量避免大对象。 内存分配有两种方式:指针碰撞和空闲列表分配。
指针冲突:存储器使用的GC算法在标记整理和复印算法时,存储器是整齐的。此时,我们只需要将存储器移动到指针的位置来分配给对象。Serial和ParNew使用的GC回收算法是标记复制算法,内存的分配就是指针碰撞的方式。
空闲列表分配:存储器使用的GC算法在标记清除算法时,存储器是整齐的,此时保持存储器空闲列表,成为新的对象
配备存储器时,从空闲列表中找到存储器即可。CMS使用的GC回收算法是标记清除算法,内存的分配方式是空闲列表的分配。看完内存分配有疑问吗?堆内存是所有线程共享的,如果两个线程同时都想占用这一块内存空间怎么办呢?这关系到分配内存空间时的并发安全问题。 JVM提供了两种处理和安全的方法:一种是我们常用的CAS失败再试验区域锁,保证存储器分配的原子性,另一种是打开-XX:UseTLAB数是每个线程的预分配 经过这个步骤,存储器中有School实例的存储器区域:
初始存储器空间
属性的赋值操作分为三种类型,例如: 初始存储器初始存间
不要混淆这一步的初始化和类加载过程中的初始化! 类加载过程中的初始化是对类静态变量的初始化,不包括类实例变量。 实施此步骤后,uu聊天室如何存储器中的情况如下: 设置对象头
将对象的类别、对象的HashCode值、对象的GC信息、锁定信息等数据存储在对象头上。它取决于JVM实现。对方头部的信息在我们面前已经说过了,在这里不再说明。 实施此步骤后,存储器中的数据变化:
实施init初始化
此时的初始化过程才真正开始。该过程与字节代码invokespecial相对应,执行init方法。 它会执行实例化代码块、调用类的构造方法、将堆内对象的首地址赋值给引用变量。这一步之后真正可用的对象才算创建完成。
执行了这一步之后内存中的变化如下图:
总结
对象的创建过程:类元数据加载->分配内存空间并解决并发问题->初始化分配的内存空间->设置对象头信息->执行init方法进行初始化。
对象的整个创建过程必须了解JVM的存储区域,熟悉各区域存储的数据,了解在哪个过程中存储的数据。 类元数据的加载是元空间的数据来源,回顾下一个加载机制、父母委托模型、哪个场合需要打破父母委托,以前分析过JDBC的SPI机制 对象的创建都是基于堆空间的,我们可以回顾下堆空间的内存分配、GC回收算法和GC回收器。
设置对象头的信息需要理解对象头,uu聊天室如何根据对象头的数据变化可以回顾synchronized锁的升级过程。 对象创建后内存的数据变化如下: 。