你能给我一些关于对象标题中存储内容的信息吗?我知道,它可能依赖于JVM,但至少可能对HotSpot有用吗?我正在寻找第一行的具体描述.
我已经阅读了一些我无法用我发现的信息验证的信息.也许你有一个指向OpenJDK维基的链接?
我非常熟悉HotSpot中堆上对象的布局,但对于Android来说并不是那么多.
例如,在32位HotSpot JVM中,堆上的对象实现为8字节头,后跟对象的字段(一个字节用于boolean
引用,四个字节用于引用,其他所有内容按预期方式),布局以某种特定的顺序(对超类中的字段有一些特殊规则),并填充为8个字节的倍数.
我做了一些研究,但我找不到任何特定于Android的信息.
(我有兴趣优化一些极其广泛使用的数据结构,以最大限度地减少Android上的内存消耗.)
以下是我想根据我的问题提出的两个样本(假设你在JOL
这里):
Layouter layout32Bits = new HotSpotLayouter(new X86_32_DataModel());
Layouter layout64BitsComp = new HotSpotLayouter(new X86_64_COOPS_DataModel());
Run Code Online (Sandbox Code Playgroud)
并使用此示例:
int [] ints = new int[10];
System.out.println(ClassLayout.parseInstance(ints, layout32Bits).toPrintable());
System.out.println(ClassLayout.parseInstance(ints, layout64BitsComp).toPrintable());
Run Code Online (Sandbox Code Playgroud)
这是两个输出:
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 09 00 00 00 (00001001 00000000 00000000 00000000) (9)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
12 40 int [I.<elements> N/A
52 …
Run Code Online (Sandbox Code Playgroud) 使用java-9 build 9-ea + 149 和jol 0.6.
运行这个简单的代码:
ArrayList<Integer> list = new ArrayList<>();
list.add(12);
System.out.println(ClassLayout.parseInstance(list).toPrintable());
Run Code Online (Sandbox Code Playgroud)
输出:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 0e 8d 00 f8 (00001110 10001101 00000000 11111000) (-134181618)
12 4 int AbstractList.modCount (access denied)
16 4 int ArrayList.size (access denied)
20 4 Object[] ArrayList.elementData (access denied)
Run Code Online (Sandbox Code Playgroud)
此访问被拒绝的部分来自方法中的FieldData.java: …
我正在尝试使用jol
Java 9 运行程序,但没有运气.
我有以下依赖pom.xml
:
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
该计划很简单:
package org.example;
import org.openjdk.jol.vm.VM;
public class Example {
public static void main(String[] args) throws Throwable {
System.out.println(VM.current().details());
}
}
Run Code Online (Sandbox Code Playgroud)
模块描述符:
module java9 {
requires jol.core;
}
Run Code Online (Sandbox Code Playgroud)
当我从IDEA运行程序时,我看到以下输出:
# WARNING: Unable to get Instrumentation. Dynamic Attach failed.
You may add this JAR as -javaagent manually, or supply -Djdk.attach.allowAttachSelf
Run Code Online (Sandbox Code Playgroud)
我-Djdk.attach.allowAttachSelf=true
在IDEA中添加了VM参数,但它没有帮助(仍然是相同的输出).
PS我可以从类路径成功运行程序.尽管如此,如何从模块路径运行它仍然很有趣.
介绍:
我使用JOL(Java对象布局)工具来分析Java对象的内部和外部碎片以用于研究目的.
在这样做时,我偶然发现了以下内容:
x@pc:~/Util$ java -jar jol-cli-0.9-full.jar internals sun.reflect.DelegatingClassLoader
# WARNING: Unable to attach Serviceability Agent. You can try again with escalated privileges. Two options: a) use -Djol.tryWithSudo=true to try with sudo; b) echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# WARNING | Compressed references base/shifts are guessed by the experiment!
# WARNING | Therefore, computed addresses are …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Java 对象布局 ( JOL ) 来测量保存某些 Java 记录实例的对象的实例大小。使用 时,我收到一个UnsupportedOperationException
描述为“无法获取记录类上的字段偏移量”的信息GraphLayout.parseInstance
。我在使用时遇到同样的错误ClassLayout.parseClass
。
我最初使用的是 Java 20,但已降级到 Java 17。我尝试了 JOL 的最后两个版本(0.17 和 0.16)。我尝试了堆栈跟踪中的建议“无法获取字段偏移,请尝试使用 -Djol.magicFieldOffset=true”。看起来 Unsafe 中的记录不受支持HotspotUnsafe.fieldOffset
,特别是在第 647 行。
下面是一个传递异常的类和引发异常的类似记录的示例。
public class Outer {
public static void main(String[] args) {
// Passes - outputs 72
System.out.println(GraphLayout.parseInstance(new A(1, "one")).totalSize());
// Fails with UnsupportedOperationException
// "can't get field offset on a record class: private final int Outer$B.value"
// sun.misc.Unsafe.objectFieldOffset - line 648
System.out.println(GraphLayout.parseInstance(new B(1, "one")).totalSize());
}
public static class …
Run Code Online (Sandbox Code Playgroud) 我使用了一个名为JOL(Java Object Layout)的工具,它试图分析对象布局.它带有一个cli
,我用它来分析java.lang.Integer
.我看到Integer对象占用了12个额外的字节用于开销.该开销可以是4个字节用于该对象所属的类的地址,另外4个用于垃圾收集,但剩余的4个字节呢?我知道对象有一个整数hashCode值,但我不认为它是唯一的(即它不使用内存的位置,它使用原始值代替)因为:
Integer a = new Integer(12);
Integer b = new Integer(12);
System.out.println(a.hashCode() == 12 && b.hashCode() == 12);
// prints: true
Run Code Online (Sandbox Code Playgroud)
日志:
$ java -jar jol-cli/target/jol-cli.jar internals java.lang.Integer
# WARNING: Unable to get Instrumentation. Dynamic Attach failed. You may add this JAR as -javaagent manually, or supply -Djdk.attach.allowAttachSelf
# Running 64-bit HotSpot VM.
# Using compressed oop with 0-bit shift.
# Using compressed klass with 0-bit shift.
# Objects are 8 bytes …
Run Code Online (Sandbox Code Playgroud) 不经意间,我偶然发现了一个jdk-15
我不知道的变化。假设我有一个非常简单的问题:3 个整数的数组的大小是多少?为此,我使用JOL。代码相当简单:
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;
public class Array {
public static void main(String [] args){
int [] array = new int[3];
System.out.println(ClassLayout.parseInstance(array).toPrintable());
}
}
Run Code Online (Sandbox Code Playgroud)
我运行这个jdk-13
:
java -Djdk.attach.allowAttachSelf -Djol.tryWithSudo=true -cp jol-cli.jar Array.java
Run Code Online (Sandbox Code Playgroud)
我得到输出:
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 18 0e 07 …
Run Code Online (Sandbox Code Playgroud) 当使用jol的GraphLayout类打印从对象实例引用的对象的图时,某些输出条目会说“(其他)”,而不是类型和引用路径。例如,考虑以下代码,该代码显示20个随机Integer对象的列表的图形:
List<Integer> foo = new Random().ints(20).boxed().collect(Collectors.toList());
System.out.println(GraphLayout.parseInstance(foo).toPrintable());
Run Code Online (Sandbox Code Playgroud)
此代码打印:
java.util.ArrayList object externals:
ADDRESS SIZE TYPE PATH VALUE
d642ecc8 24 java.util.ArrayList (object)
d642ece0 16 java.lang.Integer .elementData[0] 212716192
d642ecf0 56 (something else) (somewhere else) (something else)
d642ed28 16 java.lang.Integer .elementData[1] 1503736768
d642ed38 16 java.lang.Integer .elementData[2] -2099759732
d642ed48 16 java.lang.Integer .elementData[3] 445566433
d642ed58 16 java.lang.Integer .elementData[4] -1528625708
d642ed68 16 java.lang.Integer .elementData[5] -555424299
d642ed78 16 java.lang.Integer .elementData[6] 1607595284
d642ed88 16 java.lang.Integer .elementData[7] 763466772
d642ed98 16 java.lang.Integer .elementData[8] 638331919
d642eda8 16 java.lang.Integer .elementData[9] -1742026575
d642edb8 16 …
Run Code Online (Sandbox Code Playgroud)