Java基础知识记录——创建一个对象涉及的面试题(一)

在这里插入图片描述

1.对象的创建过程

和类的创建类似,需要经过半初始化过程。主要经过三步。
main方法中仅有一个语句,就是new一个object,来测试分析。
编译后的字节码文件(安装jclasslib bytecode)如下:

	int a =10;
    public static void main(String[] args) {

        Object obj = new Object();
    }

查看:

0 new #2 <java/lang/Object>
3 dup
4 invokespecial #1 <java/lang/Object.<init>>
7 astore_1
8 return

主要包括三步,先在内存中new,申请一个内存空间,内存空间会对a进行半初始化,赋值为0,然后再invokespecial,调用类的构造函数,这时候才会继续对a赋值为10,最后,astore_1,将obj指向实例化的内存空间。

2.volatile

  • 1.线程可见性
  • 2.防止指令重排
    先来个测试代码在这里插入图片描述
    程序的意思是,使用flag为标记,为false时,暂停新线程。当没用volatile时,程序会一直执行,停不下来。

另外一个作用是防止指令重拍,设计代码如下,初始化都为0,
a=1; b=1;
x=b; y=a;
线程A中跑左边的赋值,线程B跑右边的赋值,当xy0时停止。
DCL(双重锁检测)可以结合懒汉模式。

懒汉模式中的应该使用DCL,并且对于实例的修饰必须加上volatile,防止第一个线程拿到锁,new了一半,被另外的线程拿去使用。

3. 对象在内存中的存储布局

在这里插入图片描述
对象头包括三部分,第一部分是identity hashcode,第二部分是gc信息,第三部分是锁的信息,比较复杂。

在这里插入图片描述

4. 对象如何定位

一是句柄池(间接选址),二是直接指针(直接寻址)。
使用句柄池的好处是gc的时候比较稳定,因为gc的时候会发生对象的复制,使用句柄池则不需要变化t,而直接指针的方式则需要频繁变化t。使用直接指针的方式是比较快。
在这里插入图片描述

5. 对象怎么分配

关于对象是否会在栈上进行分配,推荐地址:https://blog.csdn.net/o9109003234/article/details/101365108。大概就是两点,一是逃逸分析,而是标量替换。
原文:

一是逃逸分析:逃逸分析的目的是判断对象的作用域是否有可能逃逸出函数体。关于逃逸分析的问题可以看我另一篇文章:

二是标量替换:允许将对象打散分配在栈上,比如若一个对象拥有两个字段,会将这两个字段视作局部变量进行分配。

只能在server模式下才能启用逃逸分析,参数-XX:DoEscapeAnalysis启用逃逸分析,参数-XX:+EliminateAllocations开启标量替换(默认打开)。Java SE 6u23版本之后,HotSpot中默认就开启了逃逸分析,可以通过选项-XX:+PrintEscapeAnalysis查看逃逸分析的筛选结果。

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章