检查 Java 中的内存布局

Posted

技术标签:

【中文标题】检查 Java 中的内存布局【英文标题】:Examining memory layout in Java 【发布时间】:2013-01-13 08:47:50 【问题描述】:

我正在尝试继承,出于教育目的,我想检查分配给各种对象的地址和对象中的字段。有没有一个工具可以让我看到 JVM 正在使用什么内存以及它的用途。

例如,如果我有两个类:

class A  int i,j; int f  ... 
class B extends A  int c; /* more methods, overriding f and declaring new ones as well */ 

并在对象ab 中实例化这些类。

我可以使用什么工具来分析内存使用情况并准确查看为这些分配了哪些内存?

谢谢!

【问题讨论】:

是什么让您认为您可以“覆盖”字段?你不能,仅供参考。 另见Recommendations for a heap analysis tool for Java? @LouisWasserman 我相信int f ... 表示一个(包私有)方法,可以被覆盖。 @LouisWasserman 你在说'f'吗?这是一种方法。 【参考方案1】:

自从发布了原始问题后,情况发生了一些变化。

jol 工具(Aleksey Shipilev 的“java 对象布局”)现在是 OpenJDK 的一部分,允许您检查实际的内存布局和类的使用情况。 http://openjdk.java.net/projects/code-tools/jol/

示例输出如下所示:

$ java -jar jol-cli/target/jol-internals.jar java.util.HashMap
  Running 64-bit HotSpot VM.
  Using compressed references with 3-bit shift.
  Objects are 8 bytes aligned.
  Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
  Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

  java.util.HashMap object internals:
   OFFSET  SIZE       TYPE DESCRIPTION                    VALUE
        0     4            (object header)                01 00 00 00 (00000001 00000000 00000000 00000000)
        4     4            (object header)                00 00 00 00 (00000000 00000000 00000000 00000000)
        8     4            (object header)                0f 0f 3e e0 (00001111 00001111 00111110 11100000)
       12     4        Set AbstractMap.keySet             null
       16     4 Collection AbstractMap.values             null
       20     4        int HashMap.size                   0
       24     4        int HashMap.threshold              16
       28     4      float HashMap.loadFactor             0.75
       32     4        int HashMap.modCount               0
       36     4        int HashMap.hashSeed               0
       40     4    Entry[] HashMap.table                  []
       44     4        Set HashMap.entrySet               null
  Instance size: 48 bytes (estimated, add this JAR via -javaagent: to get accurate result)
  Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

【讨论】:

按类型划分的字段大小:4、1、1、2、2、4、4、8、8 [字节] 数组元素大小:4、1、1、2、2、4、4 , 8, 8 [字节] 那是什么? @Andreyua 大小为:对象引用、布尔、字节、字符、短、整数、浮点、长、双精度【参考方案2】:

我想首先有一个关于如何在某些操作系统上运行 JVM 的图像是有启发性的,所以看看The Java Virtual Machine。另外,一个相关的问题是https://softwareengineering.stackexchange.com/questions/151076/approaching-java-jvm-internals

【讨论】:

【参考方案3】:

不,不存在这样的工具,尽管this article 解释了内存布局如何工作的基础知识,例如OpenJDK。 (值得注意的是,类中的其他方法在该类的实例中占用零开销。)

【讨论】:

以上是关于检查 Java 中的内存布局的主要内容,如果未能解决你的问题,请参考以下文章

Java对象创建的过程及对象的内存布局与访问定位

Rust 中的精确内存布局控制?

Java对象的内存布局以及对象的访问定位

深入理解java虚拟机HotSpot Java对象创建,内存布局以及訪问方式

java堆中对象分配布局和访问的过程

图文详解Java对象内存布局