JVM OOP-Klass源码分析

Hotspot采用OOP-Klass模型来描述一个Java对象,OOPordinary object pointer(普通对象指针),它用来表示对象的实例信息;Klass用来表示类的元数据。

Klass

当字节码文件被JVM加载时会被封装成一个InstanceKlass对象,该对象包含了类的元数据如:常量池、父类、子类、方法、成员变量等信息。

//部分Klass内容
class Klass : public Metadata {
  //父类  
  Klass*      _super;
  // First subclass (NULL if none); _subklass->next_sibling() is next one
  //第一个子类,子类通过next_sibling关联
  Klass*      _subklass;
  Klass*      _next_sibling;
  //指向类加载器
  ClassLoaderData* _class_loader_data;
   //类作用域
   AccessFlags _access_flags;
}

//https://hg.openjdk.org/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/oops/instanceKlass.hpp
//InstanceKlass 继承自Klass
class InstanceKlass: public Klass {
 
  //类的注解
  Annotations*    _annotations;
  //数组类型的变量的Klass
  Klass*          _array_klasses;
  //类常量池
  ConstantPool* _constants;
  //Java变量数量  
  u2            _java_fields_count;
    
  // Method array.
  Array<Method*>* _methods
      
  Array<u2>*      _fields;
    
  u2              _minor_version;       

  u2              _major_version; 
}

OOP

OOP(ordinary object pointer)指的是普通对象指针,它里面包含三部分数据:MarkWord、元数据指针、实例数据。MarkWord包含了类的锁标记、gc分代年龄和对象的哈希值;元数据持有Klass指针,通过该指针可以知道对象的类型;实例数据就是对象变量的实时数据。

//https://hg.openjdk.org/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/oops/oop.hpp

class oopDesc {
//MarkWord
 volatile markOop  _mark;
  //元数据 持有Klass指针
  union _metadata {
    Klass*      _klass;
    narrowKlass _compressed_klass;
  } _metadata; 
    
  // field addresses in oop
  void*     field_base(int offset)        const;
  jbyte*    byte_field_addr(int offset)   const;
  jchar*    char_field_addr(int offset)   const;
  jboolean* bool_field_addr(int offset)   const;
  jint*     int_field_addr(int offset)    const;
  jshort*   short_field_addr(int offset)  const;
  jlong*    long_field_addr(int offset)   const;
  jfloat*   float_field_addr(int offset)  const;
  jdouble*  double_field_addr(int offset) const;
  Metadata** metadata_field_addr(int offset) const;  
}

 

MarkWord

MarkWord用来保存对象的HashCode,分代年龄和锁标志位信息

//https://hg.openjdk.org/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/oops/markOop.hpp


// Constants

  enum { 
      //分代年龄 占4个字节
      age_bits                 = 4,
      //锁标记位置 占2个字节
      lock_bits                = 2,
      //是否偏向 占一个字节
      biased_lock_bits         = 1,
      //hashcode 占用字节数量
      max_hash_bits            = BitsPerWord - age_bits - lock_bits - biased_lock_bits,
      
       hash_bits                = max_hash_bits > 31 ? 31 : max_hash_bits,
      cms_bits                 = LP64_ONLY(1) NOT_LP64(0),
      epoch_bits               = 2
  };


class markOopDesc: public oopDesc {
	enum { 
        //轻量级锁
        locked_value             = 0,
        //无锁
        unlocked_value           = 1,
        //锁监视器,重量级锁
        monitor_value            = 2,
        //gc 标记
        marked_value             = 3,
        //偏向锁
        biased_lock_pattern      = 5
  };
  //是否是偏向锁模式
  bool has_bias_pattern() const {
    return (mask_bits(value(), biased_lock_mask_in_place) == biased_lock_pattern);

  }
//持有偏向锁的线程
  JavaThread* biased_locker() const {
    return (JavaThread*) ((intptr_t) (mask_bits(value(), ~(biased_lock_mask_in_place | age_mask_in_place | epoch_mask_in_place))));

  }
  //是否有轻量级锁  
  bool has_locker() const {
    return ((value() & lock_mask_in_place) == locked_value);
  }

  BasicLock* locker() const {
    return (BasicLock*) value();
  }
  //是否有重量级锁
  bool has_monitor() const {
    return ((value() & monitor_value) != 0);
  }

  ObjectMonitor* monitor() const {
    return (ObjectMonitor*) (value() ^ monitor_value);
  }  
}


例子:

class Model
{
    public static int a = 1;
    public int b;
    public Model(int b) {
        this.b = b;
    }

   public static void main(String[] args) {
      int c = 10;
      Model modelA = new Model(2);
      Model modelB = new Model(3);
   }
}



在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值