Originally posted by gggeek
View Post
Announcement
Collapse
No announcement yet.
Java Benchmarks: OpenJDK 8 Through OpenJDK 19 EA, OpenJ9, GraalVM CE
Collapse
X
-
- Likes 2
-
Originally posted by bug77 View Post
That's a different aspect: what was benchmarked here is out-of-the-box performance. And nobody goes to prod using default settings, the JVM is highly configurable. It can be a full-time job to properly tailor the runtime for each application.
I am not a java guru, but I wonder: are there not any benchmarks stressing explicitly the GC? Or would that be something that varies too much based on each app's code and runtime execution to make meaningful comparisons virtually impossible?
- Likes 1
Comment
-
Scala dev here (so we're running every application on JVM of course). Java memory management is pretty inflexible, so you need to predict what your application's memory usage limit should be and set it beforehand. Actually, if you're running multiple application in single VM then setting memory limit per app will prevent one app killing the entire VM, so in some way that's actually good for servers.
You can safely assume that out-of-the-box memory limits are wrong and that manually setting -Xmx (and -Xms) is the bare minimum of JVM tuning (i.e. otherwise the default settings will be rather poor). Some Java authors are contemplating making the memory limits flexible, but that's (a bit shockingly) not a high priority stuff right now, see e.g.: https://mail.openjdk.org/pipermail/z...er/thread.html Instead of inventing flexible memory usage limits management, there are new options for manual tuning, e.g. https://mail.openjdk.org/pipermail/z...ay/001014.html
Another thing (already mentioned) is that the default GC changed when going from Java 8 to Java 9. Default in Java 8 (and earlier) is ParallelGC, default in Java 9 (and later) is G1GC. If you want to exclude the impact of GC settings, explicitly set the GC (e.g. use XX:+UseG1GC or -XX:+UseParallelGC) and memory limits (both -Xms and -Xmx and set -Xms to be in the same order of magnitude as -Xms).
If you want to see some apples-to-apples comparisons between Java versions then here are some:
Interestingly, one article by Java author https://kstefanj.github.io/2020/04/1...rformance.html (and subsequent changes to OpenJDK) was done after some previous tests on Phoronix:
A few weeks back a set of benchmark results comparing JDK 8 and JDK 14 were published by Phoronix. The SPECjbb® 2015 results presented in that report really caught our eyes. They don’t compare to what we have seen in our own testing and this needed some investigation.
SPECjbb®1 2015 is a good benchmark to measure the overall performance of Java and also the impact of different GC algorithms. We run it continuously in our testing. Most of the time we tune it to run with a fixed heap size, because this is a well known and good practice to get stable and reproducible results. Setting a fixed heap, using JVM options -Xmx4g -Xms4g, we get results like this.
We decided to address this problem right away and a change to improve the behavior has already been pushed to JDK 15 (JDK-8241670).
(...)
A really nice improvement to the G1 out-of-the-box performance.
- Likes 3
Comment
-
Originally posted by gggeek View Post
True. I was just giving a possible explanation for the fact that older JDK seem to be more performant than recent ones, in benchmarks.
I am not a java guru, but I wonder: are there not any benchmarks stressing explicitly the GC? Or would that be something that varies too much based on each app's code and runtime execution to make meaningful comparisons virtually impossible?
It is actually up to you to benchmark the GC, by running stress tests on your app, see where it chokes and adjust GC params accordingly. Many people or companies don't do that, but it should be part of the standard delivery pipeline, if you care about performance. In many cases, people blindly increase the heap size (-Xmx above), which has the side effect of increasing the sizes of all the memory zones. Needless to say it's the most wasteful way of fixing a performance problem.
- Likes 2
Comment
-
Originally posted by bug77 View Post
Such benchmarks would be meaningless. The GC divides memory into several areas and provides default sizes that do not choke the JVM with typical apps. It's all too easy to write a benchmark that would run into the limits of one garbage collector implementation, but not the next.
It is actually up to you to benchmark the GC, by running stress tests on your app, see where it chokes and adjust GC params accordingly. Many people or companies don't do that, but it should be part of the standard delivery pipeline, if you care about performance. In many cases, people blindly increase the heap size (-Xmx above), which has the side effect of increasing the sizes of all the memory zones. Needless to say it's the most wasteful way of fixing a performance problem.Last edited by darkonix; 26 June 2022, 12:03 AM.
Comment
-
Originally posted by darkonix View PostAlso blindly increasing -Xmx not understanding Java memory management can easily cause more out of memory errors, instead of less. The reason is that Java uses more memory than only the heap, though not as easy to predict or limit.
Article about NMT: https://shipilev.net/jvm/anatomy-qua...mory-tracking/
Example raport:
Code:Native Memory Tracking: Total: reserved=1373921KB, committed=74953KB - Java Heap (reserved=16384KB, committed=16384KB) (mmap: reserved=16384KB, committed=16384KB) - Class (reserved=1066093KB, committed=14189KB) (classes #391) (malloc=9325KB #148) (mmap: reserved=1056768KB, committed=4864KB) - Thread (reserved=19614KB, committed=19614KB) (thread #19) (stack: reserved=19532KB, committed=19532KB) (malloc=59KB #105) (arena=22KB #38) - Code (reserved=249632KB, committed=2568KB) (malloc=32KB #297) (mmap: reserved=249600KB, committed=2536KB) - GC (reserved=10991KB, committed=10991KB) (malloc=10383KB #129) (mmap: reserved=608KB, committed=608KB) - Compiler (reserved=132KB, committed=132KB) (malloc=2KB #23) (arena=131KB #3) - Internal (reserved=9444KB, committed=9444KB) (malloc=9412KB #1373) (mmap: reserved=32KB, committed=32KB) - Symbol (reserved=1356KB, committed=1356KB) (malloc=900KB #65) (arena=456KB #1) - Native Memory Tracking (reserved=38KB, committed=38KB) (malloc=3KB #41) (tracking overhead=35KB) - Arena Chunk (reserved=237KB, committed=237KB) (malloc=237KB)
Originally posted by darkonix View PostIt also doesn't consider that plus the rest of the system, it is kind of promising more memory than the system really will have available under pressure.
Comment
Comment