-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GR-58477] Reduce the complexity of Native Image reachability metadata #9679
Comments
My feedback from Spring POV:
Also we care more about the memory consumption than the image size, so please measure that on typical apps (empty WebMVC app + empty WebFLux app + Petclinic). |
Some comments from the Quarkus POV:
In general all the suggestions make sense as defaults since they lower the entry barrier, even if some of them increase the image size, so I believe it would be good to implement them while keeping the current syntax support so that users/libraries/frameworks can still |
#10178 is the first PR to implement those changes. |
This issue aims to evaluate various methods to reduce the size of the current reachability metadata required for Native Image, specified in
reachability-metadata.json
files. The tradeoff when reducing metadata size is often an increase in image size, so this evaluation will seek to determine whether the changes proposed below have an acceptable impact on image size for the benefits they bring. To do so, we will look at the impact on the various libraries in the graalvm-reachability-metadata repository and the major microservice frameworks using Native Image.Here is a summary of the current format of
reachability-metadata.json
:Include all resources from program JARs
Native Image currently needs to know the URL of every resource potentially accessed at run-time by the program. These resources can come from two sources:
Include all methods if one method is included
It is already possible to access elements of classes registered for reflection via query methods on
Class
likegetMethods()
orgetDeclaredField()
when the type is registered for reflection (see #3566). However, theMethod
,Field
andConstructor
objects obtained in this way do not support reflective access (e.g.Method.invoke()
orField.set()
) as these capabilities potentially lead to a big increase in reachable code, and therefore image size. We will however investigate whether including all methods and constructors for reflective invocation if one method or constructor is already registered (i.e. changing method reflection metadata to a single boolean choice) yields acceptable image size increases for the reduction in metadata it allows.For example, this configuration:
would become equivalent to:
thereby removing the need for the
methods
field.Evaluation
Testing on the metadata repository and microservice benchmarks yielded the following results:
This is a consequent image size increase in most cases and will not be suitable to be the default setting of Native Image. Furthermore, making new code reachable can make image builds fail, and would require some adjustments by the affected developers.
Enable all fields to be reflectively accessed by default
Whereas including methods for reflection can have an important impact on reachability, including fields is typically less of an issue. We will investigate whether enabling reflective access for fields of registered types and removing the
"all[Public|Declared]Fields"
fields in the reachability metadata JSON files causes a significant image size increase.In this case, the
"fields"
,"allDeclaredFields"
and"allPublicFields"
fields would be made obsolete, simplifying the following metadata:into :
Evaluation
Testing on the metadata repository and microservice benchmarks yielded the following results:
The image size increase looks limited in most cases, but Quarkus shows a significant increase. This looks like a good candidate for metadata simplification, but an opt-out should be maintained.
Consider all reflectively accessed types as unsafe allocated, accessed through JNI, and/or serializable
We will evaluate whether removing the
"unsafeAllocated"
JSON field or the"jni"
or"serializable"
objects in reachability metadata significantly affects image size which, along with the resource changes proposed above and the potential integration of resource bundles in the reflection metadata, could reduce reachability metadata to a single set of types, thus greatly simplifying it.A metadata file as complex as this one:
could become as simple as:
Evaluation
Testing on the metadata repository and microservice benchmarks yielded the following results:
All types registered as unsafe allocated
The image size increase looks reasonable, this looks like a good candidate for metadata simplification.
All types registered for JNI
The image size increase is consequent. All reflectively accessed types should probably not be automatically registered for JNI by default. However, adding a
"jniAccessible"
field to the reflection metadata could be a good way of reducing the metadata size without impacting image size too much.All types registered for serialization
Similarly to JNI, registering all reflectively-accessed types for serialization is a big increase in image size. There is also the added risk of making code reachable which breaks the image build. A
"serializable"
field in the reflection configuration would be an interesting addition as well.Always register all super constructors of serializable types
Serialization metadata currently requires a custom super constructor class to be specified if a non-default constructor is expected to be used. We will evaluate the impact of including all super constructors from serializable classes, thus removing this requirement. This would get rid of the
"customConstructorClass"
field in the serialization metadataEvaluation
The image size increase caused by this change is minimal. This field should be removed and all constructors registered by default.
Combined testing
We also evaluated the combined effect of the three changes causing minimal image size impact: registering all fields of reflectively-accessible types as accessed, registering those types as unsafe accessed by default, and registering all super constructors of serializable classes as potential custom serialization constructors. The results are as follows:
All in all, those results are reasonable and those three changes can be implemented in Native Image, with the maintenance of an opt-out for automatic field inclusion, as explained in the corresponding section above.
Breakdown of the metadata repository results
The text was updated successfully, but these errors were encountered: