“native”关键字和@HotSpotIntrinsicCandidate 注解的区别

问题描述

为什么要使用一个,反之亦然? 哪个性能更好?

解决方法

@HotSpotIntrinsicCandidate 注释的 javadoc 注释说明如下:

@HotSpotIntrinsicCandidate 注释特定于 HotSpot 虚拟机。它表示一个带注释的方法可能(但不保证)被 HotSpot VM 内在。如果HotSpot VM 用手写程序集和/或手写编译器 IR(编译器内在)替换带注释的方法以提高性能。@HotSpotIntrinsicCandidate 注释是 Java 库的内部注释,因此不应该具有与应用程序代码的任何相关性。”

简而言之,带有这个注解的方法可能被专门优化,但这取决于HotSpot JVM是否知道如何优化它。这意味着:

  1. 如果 HotSpot JVM 知道如何强化它,Java 方法体将被忽略。
  2. 如果 HotSpot JVM 知道如何进行内部化,Java 方法体将以正常方式使用。
  3. 实现 JVM 代码来进行内在化并非易事。
  4. 您不能在自己的代码中使用它。 (它涉及修改核心 HotSpot JVM 代码库。)

相比之下,将方法声明为 native 会告诉 JVM 它必须使用本机代码实现。 (native 方法没有主体。)该方法的本机代码实现由 JVM 提供,或者它由动态提供加载本机库或 DLL。)调用将通过 JNI/JNA 进行,并且调用序列的性能通常低于传统 Java 方法调用的性能,当然是复杂的方法调用。


所以回答你的问题:

哪个更有表现力?

复杂的方法调用会更高效。

为什么要使用一个,反之亦然?

  1. 您(一名普通 Java 程序员)无法将应用中的方法有效地标记为内在方法。常规和 native 方法是您唯一的选择。

  2. JVM 实现者有一个选择,但考虑到所涉及的额外工作,他们往往只会在一个方法能够带来显着的性能优势时才使其成为内在方法。例如,在 native 类中内化 java.io.* 方法调用是没有意义的,因为与其他事情相比,JNI 调用开销很小。