我正在尝试更改我的研究项目的 OpenJDK 源代码。我想知道在 Java 程序中调用 new 运算符时的代码流程。
class MyFirstProgram {
public static void main(String args[]) throws Exception{
System.out.println("Hello World!");
int i[] = new int[50];
}
}
在 OpenJDK 源代码中,我在 new 运算符实现中放置了几个打印内容。 (路径:OpenJDKDev/src/hotspot/share/memory/allocation.cpp)
我不确定我是否正在检查正确的内存分配文件。 似乎即使当我调用 java -version 时,它也会打印我多次输入的消息。
当我在用户 Java 程序中调用 new 时,我无法找到内存分配调用的具体执行方式(以及具体位置)。
编辑: --> 使用 JDK11。
最佳答案
我有一个坏消息要告诉你。 HotSpot 源中没有一个位置可以处理所有 Java 分配。
可能会发生分配:
- 在虚拟机运行时中;
- 在字节码解释器中;
- 在 JIT 编译的代码中:
- 由C1编译;
- 由 C2 编译;
- 由Graal等编译
每种情况的方法都有很大不同。例如。最简单的部分是 VM 运行时 - 它只是一个易于修改的纯 C++ 代码,请参阅 MemAllocator::mem_allocate
.
要修改解释器,您必须深入研究一些汇编代码,请参阅 TemplateTable::_new
.
C1分配也是用ASM编写的。不要忘记有多个分配路径:in TLAB , in Eden或回退到虚拟机运行时的缓慢路径分配。
将所有汇编代码乘以架构数量:x86、ARM、AArch64、PPC 等。
C2 是另一个挑战,因为它需要生成一些令人兴奋的 IR 图。顺便说一句,分配类实例和数组的图是不同的。如果你还想玩一下,看看GraphKit::new_instance和 GraphKit::new_array .
我并不是说“稍微改变一下分配策略”是绝对不可能的,但我想说这是一项巨大的工作,需要深入了解 JVM。
附注src/hotspot/share/memory/allocation.cpp与Java堆无关。该部分负责用于内部 JVM 目的的 native “C”分配。
关于java - OpenJDK 源代码中如何以及在何处解释分配堆内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57303600/