JVM对象创建过程及空间开辟

背景:我们在通过写代码创建一个对象时,有时会秃然想到,在创建一个对象时做了哪些事情?怎么来的这个对象?那么我们今天来了解一下创建对象的背后都发生了啥。在那之前:

 

一、对象创建过程

 首先我们通过一张图与一段代码来大概了解创建一个对象的步骤。

  1. New类名 。》 图中为New String(),指定创建的对象为String
  2. 根据new的参数在常景池中定位一个类符号的引用。》图中创建了String对象,固会去找当前对象Class。
  3. 如果没有找到这个符号的引用,说明类还没有被加载,则进行类的加载,解析和初始化。》图中为加载当前对象Class。
  4. 虚拟机为对象分配内存(位于堆中)。》为当前String对象在堆中开辟空间。原理参考下文JVM如何为对象开辟空间。
  5. 分配的内存初始化为零值(不包括对象头)。》如果是int那么为0,String则为"",对值的初始化。
  6. 调用对象的<init>方法。》图中为执行String的构造方法

本次调用的String构造方法源码:

public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

创建过程原理示例代码: 

String str = new String("Hello World");

创建过程原理图: 

 

那么经历以上步骤,我们的String对象就创建完成了,是不是很简单呢?

 

二、JVM如何为对象开辟空间

首先使用哪种算法,跟垃圾回收机制有关。

标记整理和标记压缩是指针碰撞的回收算法。指针回收会使用。

标记清除为空间列表。 创建一般使用该算法。

当然垃圾回收机制影响算法的概念,相当于做了垃圾分类的城市,你在处理垃圾的时候就要把垃圾分类再丢,如果没有做垃圾分类的城市,那么你可以直接全部丢一个袋子扔掉。这时候就是不同城市的垃圾回收机制影响你的处理垃圾的思想分类行为,同理就是垃圾回收机制影响程序的算法原理。

2.1、指针碰撞

首先Cas实现同步是在CPU层面加锁。硬件层面加锁。效率高。

原理实际上会在放入的时候调用C语言的CAS方法。Unsafe类中的compareAndSwapObject方法

这里案例的意思就是内存被obj1和obj2占用后,剩下的空间只能存放一个对象,那么如果此时多线程创建obj3和obj4,同时去抢,那么总有一个资源会抢到。当然如果说非得创建两个就会出现内存溢出的问题。

内存溢出参考:https://blog.csdn.net/qq_43227967/article/details/106054100

 

2.2、空闲列表

空闲列表存放的原则:哪块区域空闲,就会存放在哪块区域

当然如果是多线程,那么其实是有一个线程缓存区的概念,会有一块一块的区域,每一个线程对应一块区域,如果A线程满了,那么就会通过CAS机制去抢占线程B的区域。来避免同时抢占一个位置的情况。

 

三、总结

Java创建对象首先是new 类名,那么实现会根据new的参数在常量池中定义一个对该类符号的引用,如果没有找到这个符号的引用,说明这个类没有被加载,那么进行类的加载、解析、初始化。然后虚拟机为其分配内存(位于堆中)使用指针碰撞或者是空闲列表,与垃圾算法相关联,默认初始值为零。最后调用对象的init方法。完成创建。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值