JVM对象的创建过程_java创建对象的语句

createh51个月前 (02-05)技术教程11

对象的创建过程

new对象

image-20230226144541919

1:首先判断这个类有没有加载过,没有加载过的先加载到我们JVM内存中。

2:分配内存

  • 指针碰撞:默认使用,如果JVM堆中内存绝对规整,使用过的内存放一边,空闲的内存放另一边。中间放着指针分界点,在分配内存的时候将那个指针向空闲空间移动一段对象大小的距离。(垃圾收集器用的是标记整理)
  • 空闲列表:JVM堆中内存不规整,已使用和未使用的相互交错,没办法用指针碰撞,JVM必须维护一个列表,记录哪些内存块可用,在分配的时候从列表中找到一块足够放下对象的空间给对象实例,并更新列表的记录。(垃圾收集器用的是标记清理)
  • 在分配内存的时候,肯定会有并发的问题,不管哪种都存在这种问题,要争抢内存。
  • 解决并发问题的方法:1:CAS失败重试。2:本地线程分配缓冲,为了避免争抢,本地线程在堆中划一块自己专属的内存空间,本地线程只往自己的 内存空间中创建对象,默认是开启的,-XX:TLABSize 指定TLAB大小,不设置的话默认是Eden的百分之一。如果放不下就走cas。

3:初始化:给变量赋上默认值。类加载的时候会给静态变量赋上默认值。

4:设置对象头:

image-20230226145734134

对象头里边主要包含Mark Word结构(中间那个图32位的)

? 正常的对象,没有加锁的对象就是无锁态那一行,前25保存hashCode,后4为保存分代年龄<=15,后边3位保存锁的状态。

? Klass Pointer类型指针,一个对象new出来是在堆中,在这个对象头部区域有根指针指向元空间的类元信息,就是这个类型指针。比如 getClass,getMethod,getFileds… ….是通过这根指针找到的。

? 如果数组的话,会多出一块,存放数组长度占4个字节,只有数组才会有。

通过ClassLayout.parseInstance查看对象头

public static void main(String[] args) {
    System.out.println("Object --- ");
    ClassLayout layout = ClassLayout.parseInstance(new Object());
        System.out.println(layout.toPrintable());
        System.out.println("数组 --- ");
        ClassLayout layout1 = ClassLayout.parseInstance(new int[]{});
        System.out.println(layout1.toPrintable());
        System.out.println("B对象 --- ");
        ClassLayout layout2 = ClassLayout.parseInstance(new B());
    System.out.println(layout2.toPrintable());
}
static class B {
    int id;
    String name;
    byte aByte;
    Object o;
}

输出结果为:

Object --- 
java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

数组 --- 
[I object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           6d 01 00 f8 (01101101 00000001 00000000 11111000) (-134217363)
     12     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
     16     0    int [I.                             N/A
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

B对象 --- 
com.example.JvmModel.JvmTest$B object internals:
 OFFSET  SIZE               TYPE DESCRIPTION                               VALUE
      0     4                    (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4                    (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                    (object header)                           65 cc 00 f8 (01100101 11001100 00000000 11111000) (-134165403)
     12     4                int B.id                                      0
     16     1               byte B.aByte                                   0
     17     3                    (alignment/padding gap)                  
     20     4   java.lang.String B.name                                    null
     24     4   java.lang.Object B.o                                       null
     28     4                    (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total
Process finished with exit code 0

Instance size:为我们对象的大小。OFFSET:偏移量。SIZE:大小

我这电脑是64位,

Object内存

前两行是Mark down 。

第三行是Klass Point,这是开启对象指针压缩,默认开启。没有开启的话,会由8个字节组成。。

最后一行是对齐。八个字节对齐,8的整数倍。是我们对象寻址效率最优的方式。

一个Object其实大小为12字节,但是为了要对齐8的整数倍,扩充4个字节,一个Object的大小为16个字节。

数组内存

前两行依然是Mark down。

第三行是Klass Point。

第四行是数组的长度。

他的内存大小是16个字节,它不需要对齐。

B对象

前三行… … markdown Klass Point

B.id:int占4个字节。

B.aByte:byte,占用一个字节。它的下一行是内存对齐,对齐成为4个字节。

B.name:String占用4个字节,存放的内存地址。这是开启对象指针压缩,默认开启。没有开启的话,会由8个字节组成。

B.o:对象占用4个字节,存放的内存地址。

最后一行对齐8。

5:执行init方法。将成员变量真正的赋值,然后还会调用对象的 构造方法。

相关文章

【Java】Redis 保存 Java 对象_redis保存数据

1. 前言这是一篇来自2018年的文章,当时已经在现在这家公司工作。公司刚起步是购买外包公司产品做定制化开发,在开发微信版的过程中遇到了一个问题。由于微信端需要通过H5的入口进行账号的绑定,同时需要在...

求你了,别再说 Java 对象都是在堆内存上分配空间了

作者 l Hollis本文经授权转载自Hollis(ID:hollischuang)Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定...

java 二维数组开发五子棋(控制台版)人人对战

主要使用到的技术:java基础语法java面向对象思想java数组,二维数组java异常处理主要步骤和思路:1,制作一个棋盘类。棋盘类里面有行属性,列属性,二维数组属性。 有一个打印棋盘的方法。 做一...

详解 java.util.Arrays 的使用技巧

创建我们来看看,使用Arrays 怎么创建一个新的数组,一般来说,我们可以使用Arrays 的 copyOf , copyOfRange 和 fill 方法。copyOf 和 copyOfRange要...

Java Valhalla Project_阿斯顿马丁valhalla

Valhalla项目的动机和原因在本文中,我们将介绍Valhalla项目——它的历史原因、当前的开发状态,以及它发布后为日常Java开发人员带来了什么。Valhalla项目的动机和原因Oracle的J...

深圳尚学堂:干货来啦!JAVA常用代码(一)

1.获取环境变量System.getenv("PATH");System.getenv("JAVA_HOME");//2.获取系统属性System.getProperty("pencil color"...