Details
-
Enhancement
-
Resolution: Fixed
-
P4
-
8, 9, 11, 17
-
b17
-
generic
-
generic
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8332963 | 17.0.12 | Aleksey Shipilev | P4 | Resolved | Fixed | b05 |
Description
A DESCRIPTION OF THE REQUEST :
Constructor- and Method instances from the JDK reflection API contain the associated parameter- and exception types as Class<?> member field arrays. However, if no parameters or exceptions are associated with the Constructor/Method instance, empty arrays are created and initialized to the instance.
In my application the amount of reachable/long-lived zero-sized arrays originating from these reflection classes amount to tens of thousands. The proposal is to optimize the memory retention for these classes by using an array constant. For instance, the below package-private constant can be defined in AccessibleObject.java:
static final Class<?>[] NO_CLASSES = new Class<?>[0];
In the constructors of Method/Constructor classes the following code could be added:
this.parameterTypes = parameterTypes.length == 0 ? NO_CLASSES : parameterTypes;
this.exceptionTypes = checkedExceptions.length == 0 ? NO_CLASSES : checkedExceptions;
In case Constructor- and Method instances are long-lived on the heap (which is probably often the case), this minor change would reduce the number of empty arrays lurking around.
This change is also safe from an API perspective since the array is always cloned before being returned to the outside world. Callers of e.g. ::getParameterTypes will always receive a brand new array regardless of how the array is stored inside Constructor/Method classes.
JUSTIFICATION :
Reduce memory footprint for long-lived Constructor/Method objects
Constructor- and Method instances from the JDK reflection API contain the associated parameter- and exception types as Class<?> member field arrays. However, if no parameters or exceptions are associated with the Constructor/Method instance, empty arrays are created and initialized to the instance.
In my application the amount of reachable/long-lived zero-sized arrays originating from these reflection classes amount to tens of thousands. The proposal is to optimize the memory retention for these classes by using an array constant. For instance, the below package-private constant can be defined in AccessibleObject.java:
static final Class<?>[] NO_CLASSES = new Class<?>[0];
In the constructors of Method/Constructor classes the following code could be added:
this.parameterTypes = parameterTypes.length == 0 ? NO_CLASSES : parameterTypes;
this.exceptionTypes = checkedExceptions.length == 0 ? NO_CLASSES : checkedExceptions;
In case Constructor- and Method instances are long-lived on the heap (which is probably often the case), this minor change would reduce the number of empty arrays lurking around.
This change is also safe from an API perspective since the array is always cloned before being returned to the outside world. Callers of e.g. ::getParameterTypes will always receive a brand new array regardless of how the array is stored inside Constructor/Method classes.
JUSTIFICATION :
Reduce memory footprint for long-lived Constructor/Method objects
Attachments
Issue Links
- backported by
-
JDK-8332963 Reduce memory footprint of java.lang.reflect.Constructor/Method
- Resolved
- relates to
-
JDK-8332586 Avoid cloning empty arrays in java.lang.reflect.{Method,Constructor}
- Resolved
- links to
-
Commit openjdk/jdk17u-dev/060c2504
-
Commit openjdk/jdk/a3851423
-
Review openjdk/jdk17u-dev/2486
-
Review openjdk/jdk/7667
-
Review openjdk/jdk/8089
(2 links to)