前段时间,一直在看《Hotspot实战》,顺便编译了一份OpenJDK的源码,然后就在eclipse里面调试起来。

虽然我的入门语言是c/c++,但是被Java拉过来好几年了,现在再看源码,熟悉又陌生,好在慢慢找到了感觉。

这是分析Hotspot源码的第一篇,讲一下Klass和Oop这两种数据结构。

系统的介绍和讲解,可以查看https://yq.aliyun.com/articles/20279和http://www.jianshu.com/p/252e27863822这两篇文章。确实写的比较好,深入而且透彻。另外可以再看看《Hotspot实战》的第3章。

我这里主要看看Klass和Oop的内存布局。

当时看这张图的时候,有一个巨大的疑问,instanceKlass的数据结构与图不符,没有对象头(Mark和Klass这两个属性)。

真是百思不得其解。

于是,继续看源码。

1)对象头里的Klass这个属性,是一个klassOopDesc类型的指针,并不是一个指向Klass类的指针。why???

看了之前的第一篇文章,豁然开朗。在JDK8之前,方法区内的描述类型的元数据对象,也是由GC管理的。所有由GC统一管理的对象,都要继承自oopDesc,所以才会诞生klassOopDesc这个类型。从JDK8开始,类型元数据都移出了GC堆,所以Klass这个属性可以直接指向Klass类了。

2)klassOopDesc只有从父类继承过来的Mark和Klass这两个属性,并没有指向Klass类的指针,那oop是如何找到对应的Klass的呢???

klassOopDesc内部有一个方法:klass_part()

  // returns the Klass part containing dispatching behavior
Klass* klass_part() const { return (Klass*)((address)this + sizeof(klassOopDesc)); }

这个方法果然返回一个指向Klass的指针,但是计算过程比较诡异,在当前klassOopDesc对象的首地址增加sizeof(klassOopDesc)这么多空间后的地址。也就是说,一个klassOopDesc对象数据和对应的Klass对象数据,是从上到下紧密的排列着,有了klassOopDesc的指针,就能顺藤摸瓜找到对应的Klass数据。

那当初构造的时候,是按这种模式在内存分配数据的吗???

之前的第二篇文章,讲的巨细。可以看到,在类加载的过程中,构造了一个空的Klass对象,然后调用了Klass类的as_klassOop方法返回klassOopDesc的指针。

  // returns the enclosing klassOop
klassOop as_klassOop() const {
// see klassOop.hpp for layout.
return (klassOop) (((char*) this) - sizeof(klassOopDesc));
}

klassOop是klassOopDesc指针的一个别名。构造的时候,首地址减去sizeof(klassOopDesc)这么多空间后的地址。这时候,内存空间是分配出来了,具体的数据,在后续过程中填充。

最后说下看源码心得体会 :其实那张图上的数据排列结构是对的,但是具体的实现方式,如果不看源码肯定会很疑惑。另外,看到这么犀利的指针操作,对c/c++的好感真是倍增。

Klass与Oop的更多相关文章

  1. 深入解析Java反射-invoke方法

    博客原文:http://www.sczyh30.com/posts/Java/java-reflection-2/ 上篇文章中回顾了一下Java反射相关的基础内容.这一节我们来深入研究Method类中 ...

  2. 深入理解java虚拟机---对象的结构(九)

    注意: 我们可以看到的就是InstanceData的数据. 先转载一篇文章作为开头,因为讲的非常详细,我就简单加工下放到这里: 对象结构 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区 ...

  3. 深入理解多线程(二)—— Java的对象模型

    上一篇文章中简单介绍过synchronized关键字的方式,其中,同步代码块使用monitorenter和monitorexit两个指令实现,同步方法使用ACC_SYNCHRONIZED标记符实现.后 ...

  4. Java对象结构及HotSpot对象模型

    一.对象结构 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding).下图是普通对象实例与数组对象 ...

  5. 从Oop-Klass模型看透反射

    <红楼梦>第十二回,贾瑞因痴迷王熙凤,被王熙凤折腾的眼看就快不行了.当然这里面是没有多少爱的,完全因王熙凤的美貌而起.就在这时来了一个跛足道人,带来了一面宝镜,说能治好贾瑞的病.当然这可不 ...

  6. HotSpot二分模型(1)

    HotSpot采用了OOP-Klass模型来描述Java类和对象.OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass用来描述对象的具体类型. 那么为何要设计这样一 ...

  7. HotSpot源码分析之C++对象的内存布局

    HotSpot采用了OOP-Klass模型来描述Java类和对象.OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass用来描述对象的具体类型.为了更好理解这个模型, ...

  8. 深入理解Java中的反射机制和使用原理!详细解析invoke方法的执行和使用

    反射的概念 反射: Refelection,反射是Java的特征之一,允许运行中的Java程序获取自身信息,并可以操作类或者对象的内部属性 通过反射,可以在运行时获得程序或者程序中的每一个类型的成员活 ...

  9. jvm源码解读--17 Java的wait()、notify()学习

    write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...

随机推荐

  1. Java泛型学习

    1.泛型的概念 泛型即"参数化类型",就比如我们定义方法的时候,定义一个变量,称为形参,变量值根据传进去的实参的值不同而改变.而泛型的出现,就是为了解决类型也能根据传进去的类型改变 ...

  2. Finding Similar Users-Euclidean Distance Score

    Purpose: Finding Similar Users Method:  Euclidean Distance Score ex2.py critics={'Lisa Rose': {'Lady ...

  3. 禁止右键,禁止选中,禁止网页复制的Js代码

    document.oncontextmenu=new Function('event.returnValue=false;'); document.onselectstart=new Function ...

  4. 利用npm安装/删除/发布/更新/撤销发布包 --社会我npm哥,好用话不多

      一.什么是npm? npm是javascript的包管理工具,是前端模块化下的一个标志性产物 简单地地说,就是通过npm下载模块,复用已有的代码,提高工作效率   1.从社区的角度:把针对某一特定 ...

  5. 《Python编程从入门到实践》第三章_列表简介

    什么是列表呢? 官方说明就是由一些列按特点顺序排列的元素组成.其实可以看出很多个字符串的有序组合吧,里面的内容可以随时的删除,增加,修改. 下面这个就是一个列表,python打印列表的时候会将中括号和 ...

  6. node项目的基本构建流程或者打开一个node项目的流程

    1.  确立项目所需要的所有依赖.框架(比如bootstrap,vue,angular等) 2. 在项目的根目录下创建一个package.json文件,package.json文件是项目的最重要文件之 ...

  7. django ngRoute ui-router 开发环境下禁用缓存

    问题描述: Python manage.py runserver ,禁用缓存,及时修改反馈到浏览器 解决办法: 使用dummy cache: Dummy caching (for developmen ...

  8. JAVA 基础知识学习笔记 名称解释

    Java ee:​ IDE: ​ itegrity   development environment 集成开发环境 JMS:​ java Message Service java   信息服务 JM ...

  9. 原生js实现Ajax的原理。

    Ajax(Asynchronous JavaScript and XML)表示异步的js与xml. 有别于传统web的同步开发方式. 原理:通过XMLHttpRequest对象向服务器发送异步请求,从 ...

  10. windows下python连接oracle数据库

    1.首先安装cx_Oracle包2.解压instantclient-basic-windows.x64-11.2.0.4.0.zip到c:\oracle3.拷贝instantclient_11_2下所 ...