quarkus
quarkus copied to clipboard
Regression in native binary size 2025-06-10
Describe the bug
On June 10 we observe an increase in the binary size and build-time RSS usage.
The changes triggering the increase appear to be between https://github.com/quarkusio/quarkus/commit/4ccce0f135627b399e5d5e7030ae74b2807664c9 (last known good) and https://github.com/quarkusio/quarkus/commit/a6f533e67a95157a6772022d2a95793eb128f03b (first known bad)
See https://github.com/quarkusio/quarkus/compare/4ccce0f135627b399e5d5e7030ae74b2807664c9...a6f533e67a95157a6772022d2a95793eb128f03b for the diff (which looks hibernate-heavy so I am CCing @yrodiere)
I am attaching screenshots and the json files with raw numbers for the integration tests main and jpa-postgresql.
Main
JPA postgresql
/cc @Karm (native-image), @galderz (native-image)
The upgrade to ORM 7 could certainly explain this. Perhaps the switch from hibernate-commons-annotations to hibernate-models matters, too.
A lot of the things happening here might be a "there are just more classes" situation, but I'm rather concerned about two things:
- The "heap_bytes" increasing significantly. @zakkak does that include metaspace (or the native equivalent), or is it strictly just objects on the heap?
- Reflection classes increasing by +400. That's wild.
FWIW, here's the diff of relevant info on jpa-postgresql.json
"image_size_stats": { "image_size_stats": {
"total_bytes": 88840640, | "total_bytes": 92035520,
"code_cache_bytes": 42533808, | "code_cache_bytes": 43722560,
"heap_bytes": 45887488, | "heap_bytes": 47890432,
"resources_bytes": 175648, "resources_bytes": 175648,
"resources_count": 61, "resources_count": 61,
"other_bytes": 419344, | "other_bytes": 422528,
"debuginfo_bytes": 0 "debuginfo_bytes": 0
}, },
"jni_classes_stats": { "jni_classes_stats": {
"id": 2455065, | "id": 2455717,
"classes": 62, "classes": 62,
"fields": 67, "fields": 67,
"methods": 55 "methods": 55
}, },
"reflection_stats": { "reflection_stats": {
"classes": 6507, | "classes": 6963,
"fields": 219, | "fields": 345,
"methods": 5640 | "methods": 5975
}, },
"build_perf_stats": { "build_perf_stats": {
"total_build_time_sec": 166.6170712, | "total_build_time_sec": 173.153532815,
"gc_time_sec": 18.524, | "gc_time_sec": 18.63,
"num_cpu_cores": 4, "num_cpu_cores": 4,
"total_machine_memory": 16469127168, | "total_machine_memory": 16469131264,
"peak_rss_bytes": 3881369600, | "peak_rss_bytes": 4006846464,
"cpu_load": 3.3938781368866775 | "cpu_load": 3.4149626193504576
}, },
"total_classes_stats": { "total_classes_stats": {
"classes": 22839, | "classes": 24083,
"fields": 45898, | "fields": 46816,
"methods": 186669 | "methods": 193557
}, },
"reachability_stats": { "reachability_stats": {
"classes": 20333, | "classes": 21454,
"fields": 28265, | "fields": 28643,
"methods": 102407 | "methods": 104879
}, },
Also, for debugging... I think I can find a way to list the reflection classes, as I've done it before, but do you know how I could get a dump of that "heap" that increased significantly? Maybe some JVM dump just before native compilation happens? If so, any idea where exactly in the code I should stop the JVM for the heap dump?
The "heap_bytes" increasing significantly. @zakkak does that include metaspace (or the native equivalent), or is it strictly just objects on the heap?
It's just objects AFAIK.
I think I can find a way to list the reflection classes
Note sure how you achieved this (I am interested in learning so please share if you do it again), but I usually start by inspecting the Quarkus-generated reflect-config.json file in the jar file passed to native-image.
do you know how I could get a dump of that "heap" that increased significantly? Maybe some JVM dump just before native compilation happens? If so, any idea where exactly in the code I should stop the JVM for the heap dump?
You can use at "run-time" -R:+DumpHeapAndExit
See https://www.graalvm.org/jdk21/reference-manual/native-image/guides/create-heap-dump/ for more info.
Hope to not be too OT, since IDK if we're taking about switching to HB 7 from 6.x; if it's the case I remember that long time ago I have used both JFR and async-profiler (tracing class define) and found, in JVM mode a big increase of class define/load of antlr 4 classes (which are pretty heavy too..). I don't remember If it was an analysis I have performed in wildfly (for Scott Marlow) but I remember I have disclosed it to @Sanne at the time. Hope it can help; if not, ignore me ❤️
@franz1981 the upgrade to ANTLR4 was included a long time ago though, that happened when we upgraded from ORM 5 to 6. We're now updating to 7 from 6, both use the same ANTLR version. (The issue with ANTLR 4 was never addressed, but it should be unrelated with this particular regression)