对象的实例化(尚硅谷自学笔记)

创建对象的方式

img

代码从字节码方式看
public void static main(String[] args){
	Object obj = new Object();
}

img

①在字节码文件中,首先new了一个#2链接的东西,在方法区的运行时常量区找到指向的是Object

②dup是复制的意思,当new了一个obj后,将obj放入操作数栈,随后复制一个也放入操作数栈,底部的用来赋值,压在上面的负责调用方法。

③invokespecial是调用Object的构造器

④将操作数栈中的obj出栈存入局部变量表

⑤放回

创建对象的步骤

img

1.判断对象的类是否加载连接初始化

虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化。(即判断类元信息是否存\在)。如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader+包名+类名为Key进行查找对应的.class文件。如果没有找到文件,则抛出ClassNotFoundException 异常,如果找到,则进行类加载,并生成对应的Class类对象

2.为对象分配内存

①如果内存规整

img

img

②如果不规整

img

选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

3.处理并发问题

①采用CAS失败重试、区域加锁保证更新的原子性

CAS是啥?

CAS是3个英文单词Compare And Swap的首字母,翻译过来就是比较并且替换。

CAS机制中使用了三个基本操作数:内存V,旧的预期值A,要修改的新值B

更新一个变量时,只有当变量的预期值A和内存地址V的实际值相同时,才会将内存地址V对应的值修改成B。

空口无凭,我们来看一个例子

img

img

img

img

从思想上来说,synchronized属于悲观锁,悲观的认为程序中的并发情况严重,所以严防死守,CAS属于乐观锁,乐观地认为程序中的并发情况不那么严重,所以让线程不断去重试更新。

在java中除了上面提到的Atomic系列类,以及Lock系列类夺得底层实现,甚至在JAVA1.6以上版本,synchronized转变为重量级锁之前,也会采用CAS机制。

②每个线程预先分配一块TLAB 通过-XX:+/-UseTLAB参数来设定

堆空间中为了防止线程的抢占调用,分配了一个线程私有的TLAB区域就可以不用采取同步也可以让并发安全了,因为只有一个线程能够操作TLAB

4.初始化分配的空间

属性的默认初始化可以保证对象在不赋值可以直接使用

5.设置对象头

img

6.执行init方法初始化

img

对象的内存布局

img

代码:

public class customer{
    int id = 1001;
    String name;
   	Account acct;
    {
        name =“匿名客户";
    }
    public customer(){
        acct = new Account();
    }
class Account{
}
    
public static void main(){
	Customer cus = new Customer();
}

代码对应内存布局的图示

img

对象的访问定位

Jvm是如何通过对象引用访问到其内部的对象实例的呢

img

访问方式

①句柄访问

img

好处:reference中存储稳定句柄地址,对象被移动(垃圾收集时移动对象很普遍)时只会改变句柄中实例数据指针即可,reference本身不需要被修改。

②直接指针(hotspot采用)

img

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值