2 Java对象的创建过程

九路
• 阅读 935

JAVA中创建对象直接new创建一个对象,对么对象的创建过程是怎样的呢? 程序运行过程中有许多的对象被创建出来.那么对象是如何创建的呢?

一 对象创建的步骤

  • 1 遇到new指令时,检查这个指令的参数是否能在常量池中找到一个符号引用
  • 2 如果找到符号引用,就检查这个符号引用是否已经被加载,解析和初始化过
  • 3 如果没有加载过,则执行类加载过程
  • 4 为对象分配内存(对象所需的内存在类加载的时候就可以确定) 指针碰撞法 : 假设java堆中的内存是规整的,所有用过的内存放在一边,空闲的内存放在另一边中间放着指针作为分界点,那分配内存就是指针向着空闲的那一边移动一段与对象大小相等的距离就行了. 空闲列表法 : 如果Java堆中的内存不是规整的,已使用的内存和空闲的内存相互交错存放,那就没有办法用指针碰撞法了,虚拟机就需要维护一个列表,记录哪块内存是可用的,哪块内存是空闲的,在分配内存的时候,从列表中找到一块足够大的内存空间划分为对象实例,并更新列表
  • 5 分配完内存后,虚拟机需要将分配到的内存初始化为0

问题如下: 上面两种内存分配的方法还带来了另外一个问题,即多个线程同时分配内存的情况下的安全问题

例如: 指针碰撞法,指针的指向还没有来得及更改的时候,另一个线程又使用了原来的指针分配内存的情况

解决方法: 对分配内存的动作进行同步加锁处理 把内存分配的动作在按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为 本地线程分配缓冲(Thread Local allocation Buffer, TLAB).哪个线程要分配内存,就先在自己的TLAB中进行,只有TLAB用完了之后并分配新的TLAB时,才需要同步锁定. 注:虚拟机是否需要开户TLAB,可以通过参数来设定

在上面的工作都完成后,从虚拟机的角度来看,一个新的对象已经产生了,但从Java程序员的角度来看,对象创建才刚刚开始,init方法还没有执行,所有的字符还是0,所以一般来说,执行new指令后会接着执行init方法,把对象按照程序员的意愿进行初始化,这样一个真正的对象才算完全产生出来.

点赞
收藏
评论区
推荐文章
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
浩浩 浩浩
2年前
JVM--对象创建过程
类创建总结根据new的参数在常量池种寻找一个类的符号引用,如果类没有被加载,则进行类加载、解析、初始化。<cinit
xiguaapp xiguaapp
1年前
垃圾回收机制
GC标记算法对象被判定为垃圾的标准:没有被其他对象引用引用计数算法:判断对象的引用数量:通过判断对象的引用数量来决定对象是否可以被回收每个对象实例都有一个引用计数器,被引用则1,完成引用则1任何引用计数为0的对象实例可以被当做垃圾收集优点:执行效率高,程序执行受影响较小。
Wesley13 Wesley13
1年前
java 复制Map对象(深拷贝与浅拷贝)
java复制Map对象(深拷贝与浅拷贝)CreationTime2018年6月4日10点00分Author:Marydon1.深拷贝与浅拷贝  浅拷贝:只复制对象的引用,两个引用仍然指向同一个对象
Easter79 Easter79
1年前
String 和 new String()的区别
String和newString()的区别ForExampleStringstr1"ABC"Stringstr2newString("ABC");Stringstr1"ABC";可能创建一个对象或者不创建对象。如果"ABC"这个字符串z在javaString池中不存在,会在javaString池中
Stella981 Stella981
1年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
1年前
java疑问
1\.newString("abc")究竟创建几个对象?答:一个或两个,如果常量池中原来有"abc",那么只创建一个对象;如果常量池中原来没有"abc",则创建两个对象. newString("abc")调用publicString(Stringoriginal)构造函数,等于"abc"和newString()两个操作,
Wesley13 Wesley13
1年前
Java中的引用类型和垃圾回收
强引用StrongReferences  强引用是最常见的引用:  比如:StringBufferbuffernewStringBuffer();  创建了一个StringBuffer类的对象,并用一个变量buffer存储对这个对象的引用。这就是个强引用。  变量持有的是这个对象的引用。通常,引用是一个对象的存储地址。
Stella981 Stella981
1年前
Clone
Java中对象的创建clone顾名思义就是复制,在Java语言中,clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。那么在java语言中,有几种方式可以创建对象呢?1使用new操作符创建一个对象2使用clone方法复制一个对象那么这两种方
helloworld_34035044 helloworld_34035044
6个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为