java - OpenJDK 源代码中如何以及在何处解释分配堆内存?

标签 java jvm adoptopenjdk

我正在尝试更改我的研究项目的 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_instanceGraphKit::new_array .

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

附注src/hotspot/share/memory/allocation.cpp与Java堆无关。该部分负责用于内部 JVM 目的的 native “C”分配。

关于java - OpenJDK 源代码中如何以及在何处解释分配堆内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57303600/

相关文章:

java - DCEVM 代码重定义已禁用

java - Java 7 中的 multi-catch 是如何实现的?

java - 野蝇服务器如何部署 war ?

java - AdoptOpenJDK 的 JRE 11+ 是否和在 JDK 上使用 jlink 一样,添加所有依赖项

java - CrudRepository 中的 findById(ID) - 尝试使用不兼容的返回类型

java - MapStruct @SubclassMapping 通过鉴别器字段

java - 使用 java 和 iText 签署 PDF 哈希值

java - java类加载器如何识别重复的类?

jvm - javac 也内联吗?