性能问答>如何计算静态变量的内存地址相对其Class对象内存地址的偏移量呢>
15回复

如何计算静态变量的内存地址相对其Class对象内存地址的偏移量呢



114.png
115.png

我在一篇文章中看到这么一段话,我想验证一下
对于HotSpot VM的对象模型,静态字段的“偏移量”就是:

  • JDK 6或之前:相对该类对应的InstanceKlass(实际上是包装InstanceKlass的klassOopDesc)对象起始位置的偏移量
  • JDK 7或之后:相对该类对应的java.lang.Class对象起始位置的偏移量。

希望大大们能帮忙解答,感激不尽

5734 阅读
请先登录,再评论

JDK6一开始是计算是相对于instanceKlass的,大概逻辑如下:

next_static_oop_offset      = (instanceKlass::header_size() + 
		 		  align_object_offset(vtable_size) + 
				  align_object_offset(itable_size)) * wordSize;
 

JDK6后面某个版本有了Mirror的结构,才开始相对Class对象了

static void init_offset_of_static_fields() {
    // Cache the offset of the static fields in the Class instance
    assert(_offset_of_static_fields == 0, "once");
    _offset_of_static_fields = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->size_helper() << LogHeapWordSize;
  }

上面之所以有一些大小差异,是因为java.lang.Class对象本身就有一定大小,并且有一些实例字段,占了一部分

2年前
回复 你假笨:

好的,谢谢假大

2年前回复
回复 难得今生共此时:

这块逻辑比较复杂,如果有兴趣,你可以看下这块代码,classFileParser.cpp: ClassFileParser::layout_fields

2年前回复
查看更多

不会是java.lang.Class对象的起始位置,这本身就是一个heap里的对象,所以和它的偏移量没任何关系,都是相对InstanceKlass的

12年前
回复 Balloon:

变量的引用本身并没有多大吧,基本都是8个字节,而且图中静态变量的内存地址的确是与其Class对象内存地址很接近

2年前回复
回复 难得今生共此时:

偏移量并不是你定义的顺序,会根据大小做一个归类,相同大小,不同类型的会放到一块,尽量避免gap过大

2年前回复
回复 Balloon:

java8之后静态变量是在Class对象的尾部,就像你看到的第一张截图,类加载都会在堆中创建唯一的Class对象,所以静态变量是在堆中,是由可能的,关键怎么验证内存地址的相对偏移量

2年前回复