JDK-8357728 : Optimize Executable#synthesizeAllParams
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2025-05-25
  • Updated: 2025-07-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 26
26Unresolved
Related Reports
CSR :  
Relates :  
Description
A DESCRIPTION OF THE PROBLEM :
Executable#synthesizeAllParams creates many duplicate parameter name Strings such as "arg0", "arg1", etc. In an typical Spring Boot application we can observe thousands of such Strings. The method can cache the most common parameter names, much like the optimization that was done in JDK-8341755.

See example for the proposed change here: https://github.com/openjdk/jdk/commit/622a46c1bd5f9d01d15412a2d03b95935a6477ce



Comments
A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/25961 Date: 2025-06-24 22:32:30 +0000
24-06-2025

I think if the problem is with that ad-hoc parameter names are retained in an array, an approach can be to stop creating parameter names in synthesizeAllParams. Parameter class already checks for null name.
11-06-2025

> The method can cache the most common parameter names, much like the optimization that was done in JDK-8341755. The reporter links the motivation for this change to the change that was done in JDK-8341755. I think it's better to leave out JDK-8341755 from this discussion because looking at what was done in that issue, the primary change there appears to be prevention of an array creation (containing the String instances). That's different from what's being proposed here where the reporter is suggesting that we use String literals for 6 common argument names (arg0 through arg5) instead of constructing those String instances dynamically. > The report was spurred by observing heap dumps of several applications, and consistently seeing duplicate "arg0", "arg1", "arg2", etc strings, amounting to 100KB+ of waste, which in the grand scheme of things is not huge but it seems rather trivial to fix There's always a balance between improving performance and micro optimizing code. I think in context of real world applications, 100KB is not big enough to be introducing caching of String literals in Java code. At least not without additional details which show that the java.lang.reflect.Parameter instances (which hold these String values) is causing genuine issues with memory consumption. Not just that, my understanding is that several garbage collectors already do String deduplication at runtime (launching java with the "-XX:+UseStringDeduplication" enables it). JEP-192 has the details about String deduplication https://openjdk.org/jeps/192 Andrew [~tongwan], can we ask the reporter to try using the "-XX:+UseStringDeduplication" when launching java to see if it helps that specific application? If that doesn't help, then please ask the reporter to provide a few more details about the application which reproduces the issue. I think it's OK if they point us to some commonly used Spring Boot tutorial or any such material which helps us build and run the application to understand what those 100KB+ of duplicated String instances are. It would also be useful to know how long the application was running when the reporter found these duplicated String instances and which profiler or tool was used to identify this. If the application was short lived or if they took a snapshot early in the application's lifetime, then it would be good to wait for a longer amount of time to check if those duplicates have been deduplicated. The other important detail would be the GC that's being configured (if any) by this application. Finally, the output of "java -version" against which this reproduces will be useful too. These details should then help us understand if there's a genuine issue that requires a fix/change.
11-06-2025

Please ask the submitter to try building an OpenJDK build out of this patch: https://github.com/openjdk/jdk/pull/25563 And see if the observed symptoms in spring boot still exists.
31-05-2025

In my investigation, another thing I noted is that parameter objects are not shared - they indeed can't be due to themselves exposing the backing executable, but we still should copy parameter from the root reflective executable to the leaf executable, as otherwise we will make too many downcalls to the VM. That said, I think I will try out optimization as outlined in JDK-8357737 - I am on a break right now so it might take a while. Once a prototype is ready, I might need you to build the patch and experiment with the custom build and see if the parameter overheads are reduced as a result, unless you can provide a public reproducer project to test with.
30-05-2025

Additional Information from submitter: ======================================= Our applications are compiled with the -parameters flag. However, there are legacy libraries that may not have been recompiled with the flag. Instances from such libraries may be used as beans, and various Spring reflection machinery such as AOP / Security will inevitably scan and cache the methods. It seems infeasible to update every single library, some of which may be OSS or depended on transitively. Separately, another observation is that some of these synthesized parameter names are coming from JDK classes (Object); I've observed that with OpenJDK 24.0.1, as well as other distributions such as zulu. The report was spurred by observing heap dumps of several applications, and consistently seeing duplicate "arg0", "arg1", "arg2", etc strings, amounting to 100KB+ of waste, which in the grand scheme of things is not huge but it seems rather trivial to fix; so regardless or wheter or not "synthesizeAllParams" should be called, it seems in practice it is.
28-05-2025

Please ask the submitter for a reproduction "spring boot" case, preferably one compiled with -parameters, or point to where Spring boot is accessing Executable.getParameters.
27-05-2025

Also, per my knowledge, Spring boot uses parameter reflection and asks programmer to use -parameters to compile - this means the resulting binary never hits synthesizeAllParams. I wonder where such strings come from in spring boot - it's possible that they are accessing the parameters for the wrong methods, or they may be accessing out of the motivation outlined in JDK-8357737, in which case that bug is a better overview of the whole situation.
26-05-2025

I doubt the validity of this issue - for class files with MethodParameters attribute, thousands of strings are created from the UTF8 entries, and they are not interned as well. See Reflection::new_parameter in reflection.cpp. In this case, the deduplication of synthesized methods might not be as much of an optimization as assumed. Since parameters are already lazy (parameterData method), I think the best way is for reflection users to check the method or constructor they are accessing before accessing the parameters. IMO the best approach may be to make parameter name fetching lazy into another pass, in case users access parameters to get correct mapping of generic types (a known shortcoming of getGenericTypes) because these are valid use of parameter that don't want name overhead. In comparison, 8341755 was required to address an overhead from capturing lambdas - field names are required while parameter names, especially meaningless ones, are often more avoidable.
26-05-2025