美文网首页
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