当前位置: 首页 > 知识库问答 >
问题:

热点JVM在堆栈替换编译期间是否执行转义分析?

戈睿识
2023-03-14

考虑以下代码:

void methodWithOSR() {
    Foo foo = new Foo(); // this object doesn't escape
    for (int i = 0; i < 1_000_000; i++) {
        // some code that uses `foo`
    }
}

当 C2 OSR 编译开始时,热点 JVM 是否能够在堆栈上标量化 foo?我想这可能是有问题的,因为活动对象已经存在于堆中,所以可能无法将对象从堆“移动”到堆栈和寄存器。

共有1个答案

羿经武
2023-03-14

在这种情况下,不太清楚“scalaraize”是什么意思,但是让我解释一下这个问题。

HotSpot JVM在OSR编译期间是否运行Escape Analysis?

对大多数编译器功能/优化对OSR编译都有效,就像对常规编译一样。

HotSpot在这里的Foo实例的“缩放”(无论它是什么意思)方面是否受益于转义分析?

标量替换的主要目标是分配消除,这不适用于 Foo 实例,因为对象已在堆中分配。

HotSpot会把活的对象从堆移到栈吗?

不,这样做没有意义。堆栈只是另一个内存区域。

热点可以优化对此处 Foo 字段的访问吗?

是的。例如,它可以在寄存器中缓存字段,例如,在这种情况下。但是,修改仍将写回堆中。

 类似资料:
  • 问题内容: 他们两个几乎都做同样的事情。确定该方法很热,然后编译而不是解释。使用OSR,您只需在编译后立即转到编译版本,而不像JIT,后者是在第二次调用该方法时调用已编译的代码。 除此之外,还有其他区别吗? 问题答案: 通常, 即时 编译是指在运行时编译本机代码并执行它,而不是(或除了)进行解释。某些虚拟机(例如Google V8)甚至都没有解释器;这些虚拟机甚至没有解释器。他们通过JIT编译执行

  • 问题内容: 他们两个几乎都做同一件事。确定该方法很热,然后编译而不是解释。使用OSR,您只需在编译后立即转到编译版本,而不像JIT,后者是在第二次调用该方法时调用已编译的代码。 除此之外,还有其他区别吗? 问题答案: 通常,即时编译是指在运行时编译本机代码并执行它,而不是(或除了)进行解释。某些虚拟机(例如Google V8)甚至都没有解释器;这些虚拟机甚至没有解释器。他们通过JIT编译执行的每个

  • 我在HashMap中存储的对象作为键覆盖equals(),但不是hashCode();当我在映射中放置一个对象时,equals()方法没有被调用。如果我还重写hashCode(),则会调用equals()方法。为什么? 为什么我不能使用自定义的equals方法来阻止向映射中添加对象,而不管我是否重写hashCode()? 谢谢 如果注释了hashCode(),则大小为2,否则大小为1。 我在想,如

  • 问题内容: 每当加载一个类时,什么存储在堆中以及什么存储在堆栈中? 线程也驻留在哪里? 问题答案: 引用类型在堆中。 任何原始类型的数据和对堆上值(方法的参数/局部变量)的引用都在堆栈上。 每个线程都有自己的堆栈。 应用程序中的所有线程共享同一堆。

  • 我来自C/C++背景,在这里一个进程内存分为: null 我想把我的注意力集中在这一点上,当我阅读JVM中的堆和堆栈时,我们是在谈论堆栈和堆的概念吗?并且整个JVM的实际内存驻留在堆上(这里指的是堆的C++概念)?

  • JVM规范(JSE 8版)提到: 第12页:2.5.2 JVM堆栈:“因为JVM堆栈除了用于推送和弹出帧之外,从来没有被直接操作过,所以帧可以被堆分配。” 第15页:2.6:帧:“帧是从创建帧的线程的JVM堆栈中分配的。”在第16页:“请注意,由线程创建的框架是该线程的本地框架,不能被任何其他线程引用。” 这听起来让我很困惑。既然一个帧是创建该帧的线程本地的,为什么要在堆中分配该帧,因为堆在所有J