I. Introduction
GraalVM 21.2 has been released. In this article, we will focus on the most obvious, important, and exciting updates in this version.
First of all, GraalVM 21.2 version can be downloaded from the following places:
GraalVM consists of several components, and in each version, we are working hard to improve them. So, if you are interested in a particular component, and hope to get a more detailed overview of the changes, please see the documentation .
Two, Native Image
Let's start with the notable new content in Native Image. As early as June, we released new Gradle and Maven plugins for Native Image, and provided the original JUnit5 support. It simplifies the process of building the Native Image of your application, and allows you to test the running of your code in the Native Image mode using JUnit.
Illustration: An example of Gradle output when running a JUnit test in native image mode.
Since the initial version was released, there have been two minor versions that have fixed, improved and cleaned up various bugs, so if you maintain an application or library that uses Native Image, consider running the two tests The running situation in Native Image !
Another improvement is that Native Image will now automatically delete unnecessary security providers from the image. These security providers that can be accessed will be detected by the static analyzer. This means that --enable-all-security-services
will be deprecated and will be removed in the future. You can also use -H:-EnableSecurityServicesFeature
completely disable automatic detection and manually register the provider. You can learn more details document
A very popular new feature in 21.2 is the implementation of class pre-definition to support ClassLoader.loadClass
calls at runtime. The required classes that need to be loaded at runtime must be provided to static analysis at build time so that they can be included in the closed world for analysis. The code pattern that contains classes loaded at any time during runtime can now work in native images, just as you have As expected.
Another interesting enhancement is the basis GraalVM 21.2 using -H:+AllowVMInspection
built Native Images now supports write JFR event the Java . To log JFR events at runtime, you must use the command line options -XX:+FlightRecorder
and -XX:StartFlightRecording
to enable JFR support and JFR logging. There are not many events that actually need to be implemented, but the architecture that implements them or emits them from the application code is available.
You can try the following examples to see the effect of custom events in practice:
import jdk.jfr.Event;
import jdk.jfr.Description;
import jdk.jfr.Label;
public class Example {
@Label("Hello World")
@Description("Helps programmer getting started")
static class HelloWorld extends Event {
@Label("Message")
String message;
}
public static void main(String... args) {
HelloWorld event = new HelloWorld();
event.message = "hello, world!";
event.commit();
}
}
Build it into the native image and -XX:+FlightRecorder -XX:StartFlightRecording=”filename=recording.jfr”
. You can see what the event looks like in VisualVM:
Third, the compiler update
Each update will bring incremental improvements and new optimizations in the compiler, thereby increasing some work performance. Over time, these benefits accumulate and lead to significant performance improvements. If you haven't updated recently, now is a good time to take advantage of all these improvements. In 21.2, many interesting optimizations were added to the compiler. Let's start with the components available in GraalVM Enterprise, which are part of the Oracle Java SE subscription.
We have improved the loop limit analysis the counting loop, so the compiler also analyzes the control flow before the loop to infer induction variables. This can generate more uncounted loops, as in the example below, which can be used for advanced optimization
long i = 0;
if (end < 1) return;
do {
// body
i++;
} while (i != end);
Here, the compiler may be incorporated before the cycle i
is 0
and end ≥ 1
information to prove end > i
and use this data to optimize the loop.
We also added a novel strip mining optimization for non-counting loops, which splits loop iterations into multiple parts, making them easier to optimize later. It is disabled by default; use the -Dgraal.StripMineNonCountedLoops=true
option to enable it.
We have improved the compilation of code using StringBuilder mode, and enhanced the support for these modes by making GraalVM builds based on JDK11 aware of compact strings in JDK11.
Then in terms of GraalVM Community Edition, a significant improvement of the compiler is the addition of Speculative Guard Movement optimization, which tries to move the loop invariant protection (for example: array boundary check) from the inside of the loop to the outside of the loop. This can significantly improve related work performance.
In addition, we have improved the safe point elimination mechanism long
counting cycle. The compiler can now eliminate long
induction variable, and it can statically prove that the range of the induction variable is Integer.MAX_VALUE - Integer.MIN_VALUE
. Consider this for loop example:
for (long i = Integer.MIN_VALUE;i< Integer.MAX_VALUE;i++) {
// body
}
The compiler can now statically prove that i
only iterates in the integer range, even if it is a long
integer. Therefore, there is no need to consider the situation of integer overflow, and the optimization effect of the loop is better.
In addition, there are some optimizations available in this version that are not enabled by default and are considered experimental. An Write Sinking attempts to move writes out of the loop. You can use -Dgraal.OptWriteMotion=true
enable it. Another optimization provided in GraalVM Enteprise (not enabled by default) is the novel SIMD (Single Instruction Multiple Data) vectorization optimization for sequential code. You can use the -Dgraal.VectorizeSIMD=true
option to experiment. If you are not ready to experiment on your own, please stay tuned in the upcoming independent article, we will discuss in detail what it brings you and how your code can benefit from it.
Four, multi-language and Truffle framework
Truffle been a new compilation queue inspired , enabled by default. This new heuristic improves the warm-up time in the performance of the multi-language runtime.
Here is a brief explanation of its role: Assume that the following synthesized JavaScript code is your application. Run the two functions in a loop, and both have reached the threshold of JIT compilation and need to be compiled:
function lowUsage() {
for (i = 0; i < COMPILATION_THRESHOLD; i++) {
// Do something
}
}
function highUsage() {
for (i = 0; i < 100 * COMPILATION_THRESHOLD; i++) {
// Do something
}
}
while(true) {
lowUsage();
highUsage();
}
In previous versions of GraalVM, the first-compiled algorithm worked on a first-come, first-served basis. This will result in the lowUsage
function being compiled first, rather than the more favorable order of highUsage
Now in GraalVM 21.2, this strategy is more complicated than hotness and considers multi-layer settings, compiling the first layer faster, compiling history and canceling optimization, prioritizing the code that was previously determined to be important, and code hotness And use a weighted combination of activity at the same time. All in all, this should bring better warm-up for all GraalVM languages.
There are additional configuration options to adjust the heuristic or completely disable its use. Learn more in document
Another change is that certain API calls when embedded in a multilingual context require a new version of JVMCI , which is the compiler interface used to insert the compiler into the Java HotSpot VM. All JDK versions of GraalVM releases include the new JVMCI, but if you use GraalVM language with a different JDK and enable the GraalVM compiler on the module path, please make sure to use the following JDK version that JDK-8264016 compatibility.
Otherwise, using forced context cancellation ( Context.close(true)
) or interrupt ( Context.interrupt(Duration)
) will throw an error. For the best experience, please consider using the Graa lVM distribution to run your applications or avoid using these APIs. comment describes other possible solutions.
Since we are talking about Truffle-related changes, there are some exciting updates in GraalVM 21.2 for projects that implement languages and tools on GraalVM. Truffle library can now without prior implementation of case prepare in advance for the compilation. For more detailed information, please refer to ExportLibrary.useForAOT and AOT tutorial .
Five, JavaScript
JavaScript implementation continues to add and update the implementation of the latest proposal, such as new Set method , experimental operator overloading supports or RegExp matching index proposal. You can find detailed information on how to enable these features in the release notes.
Most importantly, Graal.js enhances the development experience by tracking unhandled promise rejections options Context
By default, this option is set to none
and will not track unhandled promise rejections, but you can use the js.unhandled-rejections
option to configure and make your development easier.
Six, Ruby
Ruby has also undergone a series of continuous compatibility and performance improvements as always. A very influential additional feature is to accurately invalidate Ruby methods and constants by using assumptions for each name and each class. When loading Ruby code, due to the semantics of Ruby, methods are added one by one, and a lot of code will be executed when loading files. Based on the assumptions of each class (this is how it behaved in other Ruby implementations and TruffleRuby before this change), it will invalidate all call sites that call methods of that class. Through precise invalidation, it will only invalidate the call site that actually needs to call another method the next time it is called. This improves the warm-up of real-world code.
With these changes, we updated to Ruby 2.7.3, except that resolvstdlib was not updated (resolv in 2.7.3 has bug ). We also added a new TruffleRuby::ConcurrentMap
data structure for ruby concurrency.
For many other changes and fixes, please check the release notes .
Seven, Python
In this version, we have implemented a faster _pickle
than the pure Python version, making serialization faster.
Improved support for interoperability with other languages, so that the dict
type works the way you expect, and is now implemented using Truffle hashing.
As always, a lot of work is focused on performance improvement, especially during warm-up and shared engine configuration!
There are also compatibility improvements. Check the release notes or more details.
Eight, LLVM bitcode runtime
There are some improvements related to C++ in 21.2. We fixed the problem that the LLVM toolchain C does not work properly on MacOS 11.3. We also added support for C virtual calls through cross-language interoperability.
management mode in GraalVM Enterprise has also been improved. We musl libc
to version 1.2.2, and added support for pthreads
and pthread
management mode , which improved the compatibility with the existing native code base.
Nine, FastR
FastR continues to work on compatibility and improves its support for software packages in the 2021-02-01 CRAN snapshot:
- Test partial support for 3.0.1.
- Main support for tibble 3.0.6, vctrs 0.3.6 and data.table 1.13.6.
- Support for dplyr 1.0.3, ggplot 3.3.3 and knitr 1.31 is in progress.
If you are interested in the support of a specific package, please contact us!
Ten, WebAssembly
You can see that we have made many compatibility improvements and some bug fixes to the WebAssembly runtime to pass the test of as many NPM modules using WebAssembly as possible.
Eleven, Java on Truffle
An important part of GraalVM 21.2 for Java on Truffle is the new Hotswap plug-in API , which allows code to be reloaded without restarting the running application. This API is designed to allow framework developers to better control changes in the feedback application in response to source code edits in the IDE. It is achieved by setting appropriate hooks. The main design principle is that you can register various HotSwap listeners that will be triggered on the specified HotSwap event. For example, when the implementation of a certain service provider changes, it can re-run the static initializer, and run the hot-swapping callback or hook after the general operation.
The most amazing thing is that these API composed of ordinary Java calls-easier to integrate and maintain than any solution based on bytecode operations.
For more details, please see plug-in API document .
Another very welcome improvement to 21.2 is better bytecode scheduling, which can increase the speed of the Java interpreter used on Truffle by approximately 15-30% . The speed of the interpreter is a very important factor that affects the warm-up speed of the application.
21.2 has also improved Java's implementation of Map
, Map.Entry
, List
, Iterator
or Iterable
on Truffle objects with other languages (including Java host code) interoperability.
12. Tools
VisualVM has received many excellent improvements, including support for JDK 17 and allowing control of functions from the command line or other external tools. The latter can be achieved in the case of mounting the extended GraalVM seamless integration between VisualVM and VSCode . You can add IDE configuration integrated VisualVM to analyze your application.
Icon: Please pay attention to the VisualVM tab in the lower left corner, which contains operations that can be performed directly from VS Code.
VisualVM can now also save JFR records from real-time Java processes, and there is a new Lock Contention view in the Profiler tab. Therefore, if you use VisualVM now to meet your daily analysis needs, it is more powerful than ever.
13. Document
Last but not least, we refactored the GraalVM document on official website It can now be found in the main project GitHub.
This means that contributing to GraalVM and improving the lives of many other developers in the ecosystem is easier than ever. If you notice the use of documents that clarify or incompletely describe your favorite features or adjustment options, please consider sharing your expertise and helping the project with a pull request! If in doubt, here is a short guide on how to do this: Participate in the documentation contribution .
Please note that the GraalVM Enterprise documentation can be found at docs.oracle.com .
As with each version, we would like to thank the GraalVM community for all the collaboration, feedback and discussion, and sharing how you use GraalVM.
Please don't hesitate to let us know any and all feedback! There are a variety of channels can contact the team, you choose the most suitable channels: Slack , GitHub or Twitter , or to us send mail .
The translator said:
Hello, everyone, I am Dream Technology ( mica Zhang Yadong (160f9961301731 JustAuth open source author), Wu Lao Ye and other students who participated in translation and proofreading together late at night. We have exported and translated several GraalVM and Spring Native articles:
article list :
Translation is not easy, please help share with more students, thank you! ! ! For more wonderful articles, please pay attention to me.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。