Hotspot
采用OOP-Klass
模型来描述一个Java
对象,OOP
是ordinary 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);
}
}