quarkus icon indicating copy to clipboard operation
quarkus copied to clipboard

Regression in native binary size 2025-06-10

Open zakkak opened this issue 5 months ago • 6 comments

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

Image

main.json

JPA postgresql

Image

jpa-postgresql.json

zakkak avatar Jun 13 '25 09:06 zakkak

/cc @Karm (native-image), @galderz (native-image)

quarkus-bot[bot] avatar Jun 13 '25 09:06 quarkus-bot[bot]

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:

  1. The "heap_bytes" increasing significantly. @zakkak does that include metaspace (or the native equivalent), or is it strictly just objects on the heap?
  2. 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
        },							        },

yrodiere avatar Jun 13 '25 10:06 yrodiere

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?

yrodiere avatar Jun 13 '25 10:06 yrodiere

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.

zakkak avatar Jun 13 '25 10:06 zakkak

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 avatar Jun 13 '25 18:06 franz1981

@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)

Sanne avatar Jun 14 '25 13:06 Sanne