Java里面长什么样,Java对象在JVM中长啥样
前言
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中长啥样相关推荐
- java jvm对象_Java对象在JVM中长啥样
前言 Java 是门面向对象的开发语言,那么我们自己编写的 Java 类生成的对象是什么样的?它肯定保存在虚拟机的内存中,但它以怎样的结构来保存的呢?带着疑问往下看看. 关于Klass Java 层的 ...
- 深入理解JVM(1)——Java内存区域与Java对象
最近放暑假在家,没有实验室的工作要做,正好趁这个时间恶补了之前一知半解的JVM知识,使用的主要学习资料是周志明大大的<深入理解Java虚拟机--JVM高级特性与最佳实践>,我仔细拜读了两遍 ...
- Java虚拟机笔记(五):JVM中对象的分代
为什么要分代 为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用, ...
- 快速带你分清java内存结构,java内存模型,java对象模型和jvm内存结构!
现如今你是否有这样的感觉,无论生活还是学习,节奏都是非常的快,每天面对海量的知识信息,自己感觉都要hold不住了,每天打开微信公众号,是不是发现有几十条未读,无论是技术文章还是其他类型的文章,我们大多 ...
- 2020 idea 查看内存消耗_查看运行时某个java对象占用JVM大小及通过idea查看java的内存占用情况...
一.如果想看运行时某个java对象占用JVM内存大小,可以先将对象转换成字节类型,然后计算: List bizGroupRelatedEventInfos = bizEventVersionMappe ...
- java的两种运行机制_Java☞JVM工作原理
参考博客:1 2 3 JVM工作原理 java虚拟机体系结构 Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平 ...
- 《深入理解java虚拟机》笔记1——Java内存区域与Java对象
运行时数据区域 JVM载执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程 ...
- 为什么虚拟机上一运行就显示程序停止_五分钟学Java:如何学习Java面试必考的JVM虚拟机...
原创声明 本文首发于微信公众号[程序员黄小斜] 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 为什么要学习JVM虚拟机 最近的你有没有参加Java面试呢?你有没有发现,Java ...
- 为什么虚拟机上一运行就显示程序停止_五分钟学Java:如何学习Java面试必考的JVM虚拟机||CSDN博文精选...
作者:黄小斜 原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 为什么要学习JVM虚拟机 最近的你有没有参加Java面试呢?你有没有发现,Java面试中总是爱考一类问题, ...
最新文章
- java将本地图片转为bas64_JAVA将图片(本地或者网络资源)转为Base64字符串
- SQL注入-SQLMAP基础使用(十二)
- 如果给你机会,阿里巴巴的中层职位和马云的专属司机,你怎么选?
- mysql事务基础+基于innodb的行锁+间隙锁+如何锁定行
- 关于html和javascript在浏览器中的加载顺序问题的讨论(zz)
- vrp 节约算法 c++_滴滴技术:浅谈滴滴派单算法
- 拓扑一致体参数化的复杂模型的等几何分析计算重用
- centos 安装maven_安装及使用Jenkins
- win11 c4d如何安装 Windows11安装c4d的步骤方法
- Vijos P1304 回文数【回文+进制】
- vue echarts div变化_数据可视化之echarts在Vue中的使用
- c++:ISO C++ forbids declaration of ‘xxx’ with no type
- 移动通信3G技术概述
- golang 提示:can‘t resolve file
- 配置Tomcat 域名解析 tomcat/conf server.xml
- Python + ElasticSearch:轻松玩转跨越千年的两百三十万条地震数据
- 基于新浪微博api的微博分享功能实现
- [原创]UMail for linux邮件服务器备份/还原邮件数据与数据库
- cfd-post 流线很少
- 【读者来信】培训完没有类似的工作经验,该如何找工作?
热门文章
- AccessibilityService的具体应用场景
- python设计要求_Python高级应用程序设计任务要求
- 用python实现一个密码生成程序_Python实现密码生成器
- 计算机学院科研,科研概况
- 语言防止鼠标连点_全球化设计系列 | 多语言设计的“小锦囊”
- 列式存储ClickHouse(二)接口
- Docker实践(五)docker部署MySQL5.7
- OpenShift 4 - 获取能访问API服务的用户认证Token
- 简介NoSqlOnSql在SQL上实现NOSQL
- Visual Studio 2019 v16.6 Preview 3 发布