2 Java对象的创建过程

九路 等级 631 0 0
标签: 虚拟机后端

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方法,把对象按照程序员的意愿进行初始化,这样一个真正的对象才算完全产生出来.

收藏
评论区

相关推荐

2 Java对象的创建过程
JAVA中创建对象直接new创建一个对象,对么对象的创建过程是怎样的呢? 程序运行过程中有许多的对象被创建出来.那么对象是如何创建的呢? 一 对象创建的步骤 1 遇到new指令时,检查这个指令的参数是否能在常量池中找到一个符号引用 2 如果找到符号引用,就检查这个符号引用是否已经被加载,解析和初始化过 3 如果没有加载过,则执行类加载过程
2.Java 并行程序基础
1.初始线程:线程的基本操作 -------------- ### 1.新建线程 ### 2.终止线程 * stop > 造成数据不一致 ### 3.线程中断 public void Thread.interrupt() // 中断线程 public boolean Thread.isTnterrup
JAVA 基础2
一.运算符 ===== 1.算数运算符: -------- * +:加或正; * \-:减或负; * \*:乘; * /:除; * %:取余; * ++ :自增长运算符;写在变量前面表示先自增再赋值;写在变量后面表示先赋值再自增; * \--:自减少运算符;用法同++; 2.关系运算符:其返回的一定是布尔值; -------
JAVA入门2
> **课程地址:[https://www.imooc.com/learn/124](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fwww.imooc.com%2Flearn%2F124)** > > **powerDesign-uml下载地址:[http://www.uml.org.c
Java project 中获取hibernate的Configuration的2种方式
    方式一、通过hibernate.cfg.xml文件配置          1. hibernate.cfg.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hiberna
Java并发系列2
上一节讲到Java线程和synchronized关键字的使用。下面就开始介绍JDK中的一些好用的并发控制工具。 先来看ReetrantLock类,他可用来替换synchronized关键字,而且比synchronized关键字更为强大和灵活。 一、ReetrantLock简单示例 ================== 先看代码: publi
Java操作JSON数据(2)
Gson是Google公司发布的一个开发源码的Java库,可用于将Java对象转换为JSON字符串,也可用于将JSON字符串转换为对应的Java对象。本介绍下Gson的基本使用方法,包括序列化和反序列化;文中所使用到的软件版本:Java 1.8.0\_191、Gson 2.8.6。 1、引入依赖 ------ <dependency>
Java高级特性2
\[TOC\] ### 1\. static关键字 #### 1.1 类变量、类方法 /** * static关键字 * 类变量不用实例化,直接类名.属性名就可以使用,是类的一部分,被所有这个类的实例化所共享,也可以叫做静态变量 * 如果想让一个类的所有实例共享数据,就用类变量! *
java使用jeids实现redis2.6的key管理(2)
代码:     https://github.com/viakiba/redis 主要是:     MIGRATE,MOVE,OBJECT,PERSIST/PEXPIRE/PEXPIREAT,PTTL/TTL import org.junit.Test; import redis.clients.jedis.Jedis;
java使用jeids实现redis2.6的list操作(2)
代码:              https://github.com/viakiba/redis  import org.junit.Test; import redis.clients.jedis.BinaryClient.LIST_POSITION; import redis.clients.jedis.Jedis
java例题_21 求 1+2!+3!+...+20!的和
1 /*21 【程序 21 求阶乘】 2 题目:求 1+2!+3!+...+20!的和 3 程序分析:此程序只是把累加变成了累乘。 4 */ 5 6 /*分析 7 * 1、汲取上一题的教训,这么大的数字,long类型 8 * 2、for循环,两层,一层控制1~20,另
java入门(2)
类型系统 ---- 高级语言都有自己的类型系统。 类型系统可以划分为:强类型,弱类型 或者:静态类型,动态类型。 通俗地说,强类型就是语言比较在意不同类型的区别,会对某个类型所能作的动作进行严格审查, 而弱类型就睁一眼闭一眼,想做什么就做什么,比如c是弱类型,你本来定义了一个int,待会儿可以拿它当double来用,虽然c语言也会抱怨一下,但绝不阻
java基础专栏—ArrayFrame(2)
集合高级应用 ====== * Map--keySet() * Map--Entry:键值对的映射关系对象 * static interface Entry<K,V>(); * Map--entrySet() * getKe
java多线程(2)
java生命周期、线程通讯 ============= **一、生命周期** ----------         有关线程生命周期就要看下面这张图,围绕这张图讲解它的方法的含义,和不同方法间的区别。 ![](https://images2018.cnblogs.com/blog/1090617/201806/1090617-2018061121202
java常用类(2)
三、时间处理相关类 Date类:计算机世界把1970年1月1号定为基准时间,每个度量单位是毫秒(1秒的千分之一),用long类型的变量表示时间。 Date分配Date对象并初始化对象,以表示自从标准基准时间(称为“历元”(epoch),即1970年1月1日08:00:00GMT)以来的指定毫秒数。 示例: package cn.tanjian