Java对象在JVM中长啥样

前言

Java 是门面向对象的开发语言,那么咱们本身编写的 Java 类生成的对象是什么样的?它确定保存在虚拟机的内存中,但它以怎样的结构来保存的呢?带着疑问往下看看。数组

关于Klass

Java 层的开发可能不太熟悉 Klass,但确定熟悉 class,咱们只要知道 Klass 是 class 在 JVM 中的表示便可,即 Java class 对应 JVM Klass。C++ 中的继承关系以下:bash

class MetaspaceObj
    class Metadata
        class Klass
复制代码

Klass 类用来描述 Java 类信息,包括描述类型自身布局、类名、父类、子类、兄弟类等等。并发

关于oop

按前面 class 对应的方式,那么对象也应该有 JVM 内部与之相对应的表示吧?没错,就是 oop(ordinary object pointer),普通对象指针。它的定义以下:机器学习

typedef class oopDesc*                            oop;
复制代码

其中 oopDesc 类是全部 oop 的基类。在 JVM 中,不一样的 oop 用于描述特定类型的对象。好比类对象用 instanceOopDesc,数组用 arrayOopDesc。分布式

Klass+oop模型

Java 对象在 JVM 中的结构以下,包括 header 和对象内容。以下图中,左边的是 instanceOopDesc,即通常的类对象,header 包括了标识和元数据,标识用于存储运行时记录信息,包括哈希码、GC锁和线程锁等等。而右边的为 arrayOopDesc,即数组对象,header 多了个 length,用于记录数组长度。oop

这里写图片描述

来个demo

public class Test {

	private String[] flag = { "a", "b", "c" };
	private String name = "test";

	public static void main(String[] args) throws Exception {
		Test test = new Test();
		String _name = "test";
		System.out.println(test.flag);
		System.out.println(_name);
	}
}
复制代码

对象结构

在上面程序中打个断点,经过 jps 查出 pid,而后使用下面命令打开 hsdb,根据 pid 链接到 JVM。布局

jhsdb hsdb
复制代码

这里写图片描述

查看 main 线程的栈内存,咱们主要是要拿到 Test 对象的地址,即0x000000008a105dd0学习

这里写图片描述

接着用 inspector 来查看0x000000008a105dd0地址对应的 oop,看到这个 oop 就是咱们的 Test 类生成的对象结构了,包含了 mark 和 metadata。这里可能会有个疑问,就是前面不是说数组还有一个 length 来表示数组长度的吗?但图中的 flag 数组变量并无看到 length 啊。ui

这里写图片描述

其实数组 oop 并非没有 length,而是 C++ 并无声明这个变量,而是经过指针来直接将数组长度保存到对应的内存了,因此这里是看不到的。经过下面具体的实现代码就能清楚了解到缘由了。是否是咱们就没办法看到这个长度值呢?并非,下面继续看如何来看这个值。this

int length() const {
    return *(int*)(((intptr_t)this) + length_offset_in_bytes());
  }
  
void set_length(int length) {
    *(int*)(((intptr_t)this) + length_offset_in_bytes()) = length;
  }
复制代码

前面咱们能够获得 flag 数组 oop 的地址为0x000000008a105de8。64位机器上_mark为8字节,_metadata为4字节,那么将地址加12,获得0x000000008a105df4。而后用 hsdb 命令行的 examine 获得地址的值,获得0x8a105e0800000003,其中00000003即是。

hsdb> examine 0x000000008a105df4
0x000000008a105df4: 0x8a105e0800000003
复制代码

-------------推荐阅读------------

个人2017文章汇总——机器学习篇

个人2017文章汇总——Java及中间件

个人2017文章汇总——深度学习篇

个人2017文章汇总——JDK源码篇

个人2017文章汇总——天然语言处理篇

个人2017文章汇总——Java并发篇


跟我交流,向我提问:

这里写图片描述

公众号的菜单已分为“读书总结”、“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

为何写《Tomcat内核设计剖析》

欢迎关注:

这里写图片描述
相关文章
相关标签/搜索