diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessingContextImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessingContextImpl.java index e6109e9d2b..a6337065fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessingContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessingContextImpl.java @@ -58,6 +58,8 @@ public class ResultSetProcessingContextImpl implements ResultSetProcessingContex private List hydratedEntityRegistrationList; private int nRowsRead = 0; + private Map identifierResolutionContextMap; + /** * Builds a ResultSetProcessingContextImpl * @@ -137,15 +139,22 @@ public class ResultSetProcessingContextImpl implements ResultSetProcessingContex return LockMode.NONE; } - private Map identifierResolutionContextMap; - @Override public EntityReferenceProcessingState getProcessingState(final EntityReference entityReference) { + EntityReferenceProcessingState context; if ( identifierResolutionContextMap == null ) { - identifierResolutionContextMap = new IdentityHashMap<>(); + //The default expected size of IdentityHashMap is 21, which is likely to allocate larger arrays than what is typically necessary. + //Reducing to 5, as a reasonable estimate for typical use: any larger query can better justify the need to resize, + //while single loads shouldn't pay such an high cost. + //This can save a lot of memory as it reduces the internal table of IdentityHashMap from a 64 slot array, to 16 slots: + //that's a 75% memory cost reduction for usage patterns which do many individual loads. + identifierResolutionContextMap = new IdentityHashMap<>(5); + context = null; + } + else { + context = identifierResolutionContextMap.get( entityReference ); } - EntityReferenceProcessingState context = identifierResolutionContextMap.get( entityReference ); if ( context == null ) { context = new EntityReferenceProcessingState() { private boolean wasMissingIdentifier;