Skip to content

Difference between “native” keyword and @HotSpotIntrinsicCandidate annotation

Why use one over another and vice-versa? Which is more performant?


The javadoc comments for the @HotSpotIntrinsicCandidate annotation say the following:

“The @HotSpotIntrinsicCandidate annotation is specific to the HotSpot Virtual Machine. It indicates that an annotated method may be (but is not guaranteed to be) intrinsified by the HotSpot VM. A method is intrinsified if the HotSpot VM replaces the annotated method with hand-written assembly and/or hand-written compiler IR — a compiler intrinsic — to improve performance. The @HotSpotIntrinsicCandidate annotation is internal to the Java libraries and is therefore not supposed to have any relevance for application code.”

In short, a method with this annotation1 may be specially optimized, but it depends on whether the HotSpot JVM knows how to optimize it. The implication is that:

  1. If the HotSpot JVM knows how to intrisify it, the Java method body is ignored.
  2. If the HotSpot JVM doesn’t knows how to intrisify, the Java method body will be used in the normal way.
  3. Implementing the JVM code to do the intrinsification is non-trivial.
  4. You cannot make use of this in your own code. (It involves modify the core HotSpot JVM codebase.)

By contrast, declaring a method as native tells the JVM it must use a native code implementation. (The native method doesn’t have a body.) The method’s native code implementation may be provided by the JVM, or it may be provided by a dynamically loaded native library or DLL.) The call will typically1 be made via JNI / JNA and its calling sequence will be less performant than a conventional Java method call, and certainly an intrisified method call.

1 – In fact, the annotation is called @IntrinsicCandidate in Java 17.
2 – Some native methods in core Java SE classes (e.g. Object methods) are also marked as intrinsic. These may get optimized calling sequences.

So to answer your questions:

Which is more performative?

Intrisified method calls will be more performant.

Why use one over another and vice-versa?

  1. You (a regular Java programmer) can’t usefully label methods in your apps as intrinsic. Regular and native methods your only options.

  2. The JVM implementors have a choice, but given the extra work involved, they tend to only make a method intrinsic when it will give a significant performance benefit. For example, it makes little sense to intrinsify the native method calls in* classes because the JNI method call overheads will be tiny compared with the other things that go on in a typical I/O operation.