前言

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

关于Klass

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

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,用于记录数组长度。

来个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 啊。

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

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

复制代码

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

跟我交流,向我提问:

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

欢迎关注:

Java里面长什么样,Java对象在JVM中长啥样相关推荐

  1. java jvm对象_Java对象在JVM中长啥样

    前言 Java 是门面向对象的开发语言,那么我们自己编写的 Java 类生成的对象是什么样的?它肯定保存在虚拟机的内存中,但它以怎样的结构来保存的呢?带着疑问往下看看. 关于Klass Java 层的 ...

  2. 深入理解JVM(1)——Java内存区域与Java对象

    最近放暑假在家,没有实验室的工作要做,正好趁这个时间恶补了之前一知半解的JVM知识,使用的主要学习资料是周志明大大的<深入理解Java虚拟机--JVM高级特性与最佳实践>,我仔细拜读了两遍 ...

  3. Java虚拟机笔记(五):JVM中对象的分代

    为什么要分代 为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用, ...

  4. 快速带你分清java内存结构,java内存模型,java对象模型和jvm内存结构!

    现如今你是否有这样的感觉,无论生活还是学习,节奏都是非常的快,每天面对海量的知识信息,自己感觉都要hold不住了,每天打开微信公众号,是不是发现有几十条未读,无论是技术文章还是其他类型的文章,我们大多 ...

  5. 2020 idea 查看内存消耗_查看运行时某个java对象占用JVM大小及通过idea查看java的内存占用情况...

    一.如果想看运行时某个java对象占用JVM内存大小,可以先将对象转换成字节类型,然后计算: List bizGroupRelatedEventInfos = bizEventVersionMappe ...

  6. java的两种运行机制_Java☞JVM工作原理

    参考博客:1 2 3 JVM工作原理 java虚拟机体系结构 Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平 ...

  7. 《深入理解java虚拟机》笔记1——Java内存区域与Java对象

    运行时数据区域 JVM载执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程 ...

  8. 为什么虚拟机上一运行就显示程序停止_五分钟学Java:如何学习Java面试必考的JVM虚拟机...

    原创声明 本文首发于微信公众号[程序员黄小斜] 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 为什么要学习JVM虚拟机 最近的你有没有参加Java面试呢?你有没有发现,Java ...

  9. 为什么虚拟机上一运行就显示程序停止_五分钟学Java:如何学习Java面试必考的JVM虚拟机||CSDN博文精选...

    作者:黄小斜 原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 为什么要学习JVM虚拟机 最近的你有没有参加Java面试呢?你有没有发现,Java面试中总是爱考一类问题, ...

最新文章

  1. java将本地图片转为bas64_JAVA将图片(本地或者网络资源)转为Base64字符串
  2. SQL注入-SQLMAP基础使用(十二)
  3. 如果给你机会,阿里巴巴的中层职位和马云的专属司机,你怎么选?
  4. mysql事务基础+基于innodb的行锁+间隙锁+如何锁定行
  5. 关于html和javascript在浏览器中的加载顺序问题的讨论(zz)
  6. vrp 节约算法 c++_滴滴技术:浅谈滴滴派单算法
  7. 拓扑一致体参数化的复杂模型的等几何分析计算重用
  8. centos 安装maven_安装及使用Jenkins
  9. win11 c4d如何安装 Windows11安装c4d的步骤方法
  10. Vijos P1304 回文数【回文+进制】
  11. vue echarts div变化_数据可视化之echarts在Vue中的使用
  12. c++:ISO C++ forbids declaration of ‘xxx’ with no type
  13. 移动通信3G技术概述
  14. golang 提示:can‘t resolve file
  15. 配置Tomcat 域名解析 tomcat/conf server.xml
  16. Python + ElasticSearch:轻松玩转跨越千年的两百三十万条地震数据
  17. 基于新浪微博api的微博分享功能实现
  18. [原创]UMail for linux邮件服务器备份/还原邮件数据与数据库
  19. cfd-post 流线很少
  20. 【读者来信】培训完没有类似的工作经验,该如何找工作?

热门文章

  1. AccessibilityService的具体应用场景
  2. python设计要求_Python高级应用程序设计任务要求
  3. 用python实现一个密码生成程序_Python实现密码生成器
  4. 计算机学院科研,科研概况
  5. 语言防止鼠标连点_全球化设计系列 | 多语言设计的“小锦囊”
  6. 列式存储ClickHouse(二)接口
  7. Docker实践(五)docker部署MySQL5.7
  8. OpenShift 4 - 获取能访问API服务的用户认证Token
  9. 简介NoSqlOnSql在SQL上实现NOSQL
  10. Visual Studio 2019 v16.6 Preview 3 发布