从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的?
转载自 从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的?
先回顾一下Java程序执行的过程:
Java程序执行时,第一步系统创建虚拟机进程,然后虚拟器用类加载器Class Loader加载java程序类文件到方法区。
方法区放哪些东西?
存放加载过的类信息、常量、静态变量、及jit编译后的代码(类方法)等数据的内存区域。它是线程共享的。
方法区存放的信息包括:类的基本信息、运行时常量池、变量字段信息、方法信息等。这部分的详细介绍看下面链接的文章。
详细Java程序运行的内存结构介绍 点此处
简要过程:
类加载完成后,主线程运行static main()时在虚拟机栈中建栈帧,压栈。
执行到new Object()时,在堆heap里创建对象。
对象创建的过程就是堆上分配实例对象内容空间的过程,在堆中对象内存空间的具体结构如下:
对象头 这个头包括两个部分,第一部分用于存储自身运行时的数据例如GC标志位、哈希码、锁状态等信息。第二部分存放指向方法区类静态数据的指针。
实例变量 存放类的属性数据信息,包括父类的属性信息。如果是数组的实例部分还包括数组的长度。这部分内存按4字节对齐。
填充数据 这是因为虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐。HotSpot VM的自动内存管理要求对象起始地址必须是8字节的整数倍。对象头本身是8的倍数,当对象的实例变量数据不是8的倍数,便需要填充数据来保证8字节的对齐。另外,堆上对象内存的分配是并发进行的.
然后执行类的构造函数初始化。
Java虚拟机规范规定该区域可抛出OutOfMemoryError。
详细步骤
例如:
Dog dog = new Dog();
当虚拟机执行到new指令时,它先在常量池中查找“Dog”,看能否定位到Dog类的符号引用;如果能,说明这个类已经被加载到方法区了,则继续执行。如果没有,就让Class Loader先执行类的加载。
然后,虚拟机开始为该对象分配内存,对象所需要的内存大小在类加载完成后就已经确定了。这时候只要在堆中按需求分配空间即可。具体分配内存时有两种方式,第一种,内存绝对规整,那么只要在被占用内存和空闲内存间放置指针即可,每次分配空间时只要把指针向空闲内存空间移动相应距离即可,当某对象被GC回收后,则需要进行某些对象内存的迁移。第二种,空闲内存和非空闲内存夹杂在一起,那么就需要用一个列表来记录堆内存的使用情况,然后按需分配内存。
对于多线程的情况,如何确保一个线程分配了对象内存但尚未修改内存管理指针时,其他线程又分配该块内存而覆盖的情况?有一种方法,就是让每一个线程在堆中先预分配一小块内存(TLAB本地线程分配缓冲),每个线程只在自己的内存中分配内存。但对象本身按其访问属性是可以线程共享访问的。
内存分配到后,虚拟机将分配的内存空间都初始化为零值(不包括对象头)。实例变量按变量类型初始化相应的默认值(数值型为0,boolan为false),所以实例变量不赋初值也能使用。接着设置对象头信息,比如对象的哈希值,GC分代年龄等。
从虚拟机角度,此时一个新的对象已经创建完成了。但从我们程序运行的角度,新建对象才刚刚开始,对象的构造方法还没有执行。只有执行完构造方法,按构造方法进行初始化后,对象才是彻底创建完成了。
构造函数的执行还涉及到调用父类构造器,如果没有显式声明调用父类构造器,则自动添加默认构造器。
到此,new运算符可以返回堆中这个对象的引用了。
此刻,会根据dog这个变量是实例变量、局部变量或静态变量的不同将引用放在不同的地方:
如果dog局部变量,dog变量在栈帧的局部变量表,这个对象的引用就放在栈帧。
如果dog是实例变量,dog变量在堆中,对象的引用就放在堆。
如果dog是静态变量,dog变量在方法区,对象的引用就放在方法区。
从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的?相关推荐
- 解析 Java 类和对象的初始化过程
跳转到主要内容 中国 [ 选择 ] dW 全部内容-------------- AIX and UNIX Info Mgmt Lotus Rational WebSphere-------- ...
- Java 面向对象与对象的创建过程及变量
Java 面向对象与对象的创建过程及变量: 1.面向对象和面向过程的思想对比 : 面向过程 :是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的 面向对象 :是一种以对象为中心的编 ...
- 解析 Java 类和对象的初始化过程 由一个单态模式引出的问题谈起
在 IBM Bluemix 云平台上开发并部署您的下一个应用. 开始您的试用 问题引入 近日我在调试一个枚举类型的解析器程序,该解析器是将数据库内一万多条枚举代码装载到缓存中,为了实现快速定位枚举代码 ...
- 解析 Java 类和对象的初始化过程(zhuang张 国建 (guojian.zhang@gmail
[url]http://www.blogjava.net/rendong/default.html?page=2[/url]
- Java对象的创建过程
对象的创建过程: ①将class load到内存: ②申请内存: ③成员变量赋默认值: ④调用构造方法<init>,同时,成员变量顺序赋初始值,执行构造方法语句,会先调用父类的构造方法,有 ...
- java初始化实例化_Java对象的创建过程:类的初始化与实例化
一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...
- Java对象的创建过程:类的初始化与实例化
一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...
- java实例化类之后如何赋值_深入理解Java对象的创建过程:类的初始化与实例化...
摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...
- 深入理解Java对象的创建过程:类的初始化与实例化
摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...
最新文章
- html display布局,Web布局:display属性
- 有关递归的三道算法题总结
- python中 lambda, map ,filter ,reduce讲解
- MySQL8.0 · 优化器新特性 · Cost Model, 直方图及优化器开销优化
- 快速制作BP神经网络结构示意图
- Linux的链接工具 putty 以及一些命令。
- Linux 网络性能测试工具 iperf 的安装和使用
- 修改完out不更新_CyclicBarrier 不就是比 CountDownLatch 多了个回环么?
- syslog函数输出在哪个文件中_syslog服务详解
- 哀悼日-全网变灰效果实现
- |9 其他(linux特定的), 用来存放内核例行程序的文档.,Linux常用操作指令
- word文件打开之后不能编辑是怎么回事
- 苹果Mac系统虚拟打印机CAD输出PDF文档软件—pdfwriter
- B端产品运营:学习笔记
- 图像处理课程大设计--汽车牌照自动识别
- E4X - 维基百科,自由的百科全书
- 象与骑象人-幸福的假设
- 【软件推荐】集tftp client、Server、syslog功能于一体的绿色软件tftpd32.exe
- python笔记—文件中的f.readline()方法解析
- emwin自定义颜色
热门文章
- 7-40 奥运排行榜 (25 分)(详解+思路+map+vector做法)兄弟们冲压呀呀呀呀呀呀呀
- 7-1 寻找大富翁 (25 分)(思路加详解+两种做法(一种优先队列,一种vector容器))
- 栈在前端中的应用,顺便再了解下深拷贝和浅拷贝!
- [mybatis]Mapper XML Files_CUD
- 上元节的灯会(灭)-区间dp
- java.time.format例子_java格式化时间示例
- 【AT987】高橋君【组合数】【莫队】
- 牛客题霸 [拼接所有的字符串产生字典序最小的字符串] C++题解/答案
- 牛客题霸题目及题解汇总
- [2021-06-19] 提高组新手副本Ⅱ(联网,欧几里得,分解树,开关灯)