2

我正在尝试为我的研究项目更改 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。

4

1 回答 1

16

我有一个坏消息要告诉你。HotSpot 源代码中没有一个地方可以处理所有 Java 分配。

可能会发生分配:

  • 在虚拟机运行时;
  • 在字节码解释器中;
  • 在 JIT 编译的代码中:
    • 由C1编译;
    • 由C2编译;
    • 由 Graal 等编译。

每种情况下的方法都完全不同。例如,最简单的部分是 VM 运行时 - 它只是一个易于修改的普通 C++ 代码,请参阅MemAllocator::mem_allocate.

要修改解释器,您必须深入研究一些汇编代码,请参阅TemplateTable::_new.

C1分配也是用ASM写的。不要忘记有多个分配路径:在 TLAB中、在 Eden 中或回退到 VM 运行时的慢速路径分配。

将所有汇编代码乘以体系结构的数量:x86、ARM、AArch64、PPC 等。

C2 是另一个挑战,因为它需要生成一些令人兴奋的 IR 图。顺便说一下,分配类实例和数组的图是不同的。如果您仍想使用它,请查看GraphKit::new_instanceGraphKit::new_array

我并不是说“稍微改变分配策略”是绝对不可能的,但我想说这是一项需要深入了解 JVM 的大量工作。

PS src/hotspot/share/memory/allocation.cpp与 Java Heap 无关。这部分负责为内部 JVM 目的进行本机“C”分配。

于 2019-08-01T23:40:10.297 回答