美文网首页
JAVA Obeject o = new Object()

JAVA Obeject o = new Object()

作者: QTong | 来源:发表于2020-04-08 13:06 被阅读0次

总览

1.对象创建的过程 (半初始化)
2.DCL 是否需要 volatitle (指令重排)
3.对象内存结构(对象与数组的不同)
4.对象头包含什么 (markword klasspointer synchronized锁信息)
5.对象如何定位 (直接间接)
6.对象怎么分分配(栈 本地线程 eden old)
7.Obeject o = new Object()在内存中占多少字节

1.对象创建的过程 (半初始化)

public class T {
   int m=8;
   public static void main(string[] args){
      T t = new T();
  }
}

汇编码:

0 new #2<T>                            申请内存 (半初始化 int 0)
3 dup                    由于invoke
4 invokespecial # 3 <T.<init>>         设置初始值 调用T构造方法 0->8
7 astore_1                             t和 内存对象关联
8return

2.DCL 是否需要 volatitle (指令重排)

单例模式 资源浪费(未使用 先new)

public class T {
    private static final T INSTANCE=new T();
    private T(){};
    public static T getInstance(){ return INSTANCE;}
    public void m(){ Systrm.out.println("m");}
    public static void main(string[] args){
      T t = T.getInstance();
      T t1 = T.getInstance();
      System.out.println(t == t1)
  }
}

解决浪费按需初始化 , 线程不安全 多次new,

public class T {
    private static T INSTANCE;
    private T(){};
    public static T getInstance(){
//  按需初始化
      if (INSTANCE == null ){
        try {
            Thread.sleep(millis: 1);
        } catch (InterruptedException e){
         e.printStackTrace();
        }
        INSTANCE = new T();
       }
       return INSTANCE;
    }
    public void m(){ Systrm.out.println("m");}

    public static void main(string[] args){
        for(int i=0; i<100;i++){
            new Thread(()-> 
                    System.out.println(T.ggetInstance().hashCode())
             ).start();
        }
    }
}

线程安全 锁整个方法 效率下降

public class T {
    private static T INSTANCE;
    private T(){};
// syncnronized
    public static syncnronized T getInstance(){
      if (INSTANCE == null ){
        try {
            Thread.sleep(millis: 1);
        } catch (InterruptedException e){
         e.printStackTrace();
        }
        INSTANCE = new T();
       }
       return INSTANCE;
    }
    public void m(){ Systrm.out.println("m");}

    public  static void main(string[] args){
        for(int i=0; i<100;i++){
            new Thread(()-> 
                    System.out.println(T.ggetInstance().hashCode())
             ).start();
        }
    }
}

锁整内部方法

public class T {
    private static T INSTANCE;
    private T(){};
    public static T getInstance(){
      if (INSTANCE == null ){
    //通过减小同步代码快的方式提高效率 ,可能第一个Thread判断完了 等在这,
//第二个Tread 判断完往下走,已经给T赋值了,第一个再往下走重新newT
         syncnronized (T.class){
            try {
              Thread.sleep(millis: 1);
            } catch (InterruptedException e){
               e.printStackTrace();
            }
            INSTANCE = new T();
          }
        }
       return INSTANCE;
    }
    public void m(){ Systrm.out.println("m");}

    public  static void main(string[] args){
        for(int i=0; i<100;i++){
            new Thread(()-> 
                    System.out.println(T.ggetInstance().hashCode())
             ).start();
        }
    }
}

DCL Double Check Lock CPU指令重排序 之后 读取之前半初始化的值(volatile 保持Thread可见性,禁止指令重拍)

public class T {
    private static volatile T INSTANCE; 禁止指令重排
    private static T INSTANCE;
    private T(){};
    public static T getInstance(){
      //业务代码省略
      if (INSTANCE == null ){  //DCL
         //双重检查   
         syncnronized (T.class){
           if(INSTANCE == null){
            try {
              Thread.sleep(millis: 1);
            } catch (InterruptedException e){
               e.printStackTrace();
            }
            INSTANCE = new T();
           }
          }
        }
       return INSTANCE;
    }
    public void m(){ Systrm.out.println("m");}

    public  static void main(string[] args){
        for(int i=0; i<100;i++){
            new Thread(()-> 
                    System.out.println(T.ggetInstance().hashCode())
             ).start();
        }
    }
}
DCL指令重排

4对象内存结构(对象与数组的不同)

markword +class pointer =object header


image.png

打印对象信息

import org.openjdk.jol.info.ClassLayout;
public class HelloJOL{
public  static void main(String[] args){
object o =new Object();
String s =ClassLayout.parseInstance(o).toPrintable();
System.out.println(s);
syncnroized(o){
System.out.println(ClassLayout.parseInstance(o).toPrintable());  
}
}
}

syncronized:
锁升级:
偏向锁-->自旋锁(CAS)-->重量锁
偏向锁
贴标签 是我的标签直接使用内存
不是我的 CAS竞争

CAS


CAS

重量锁
放到os队列中 轮到你才执行(之前的都在jvm里)

5.对象如何定位 (直接间接)

对象如何定位

6.对象怎么分分配(栈 本地线程 eden old)

对象如何分配

标量替换:用成员变量即可代表这个对象
逃逸: 创建的对象只能自己用,别的方法调用不到
(jvm默认开启 上边两个)


禁用标量替换和逃逸 效率下降一半 TLAB buffer

Eden区给每个Thread 分配了一段专属内存 没有锁
符合TLAB的直接房专属内存

分代年龄15之后old

7.Obeject o = new Object()在内存中占多少字节

o oop 4个
obeject


类压缩,对象压缩

相关文章

网友评论

      本文标题:JAVA Obeject o = new Object()

      本文链接:https://www.haomeiwen.com/subject/owazphtx.html