Skip to content

Lighter interceptors: more efficient initialization and lower memory usage #10387

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

Sanne
Copy link
Member

@Sanne Sanne commented Jun 23, 2025

https://hibernate.atlassian.net/browse/HHH-19536

Exploring some internal refactoring of how two core interceptors are being initialized:

  • EnhancementAsProxyLazinessInterceptor
  • LazyAttributeLoadingInterceptor

(These two are both implementors of of AbstractInterceptor, and represent the full set of its implementors )

The goal is to both reduce allocation pressure significantly, and also reduce the amount of repeating work being done when each of these instances is being initialized. Generally speaking, we identified a significant amount of "state" which is immutable and could be shared across all such interceptor instances when they belong to the same type.

JOL provided stats, assuming 15+ JDK, COOPS, CCPS :

Before:

org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor object internals:
OFF  SZ                               TYPE DESCRIPTION                                                      VALUE
  0   8                                    (object header: mark)                                            N/A
  8   4                                    (object header: class)                                           N/A
 12   1                            boolean AbstractInterceptor.allowLoadOutsideTransaction                  N/A
 13   1                            boolean EnhancementAsProxyLazinessInterceptor.inLineDirtyChecking        N/A
 14   1                            boolean EnhancementAsProxyLazinessInterceptor.initializeBeforeWrite      N/A
 15   1                                    (alignment/padding gap)                                          
 16   4                             String AbstractInterceptor.entityName                                   N/A
 20   4   SharedSessionContractImplementor AbstractInterceptor.session                                      N/A
 24   4                             String AbstractInterceptor.sessionFactoryUuid                           N/A
 28   4                        Set<String> EnhancementAsProxyLazinessInterceptor.identifierAttributeNames   N/A
 32   4                      CompositeType EnhancementAsProxyLazinessInterceptor.nonAggregatedCidMapper     N/A
 36   4                          EntityKey EnhancementAsProxyLazinessInterceptor.entityKey                  N/A
 40   4                        Set<String> EnhancementAsProxyLazinessInterceptor.writtenFieldNames          N/A
 44   4                        Set<String> EnhancementAsProxyLazinessInterceptor.collectionAttributeNames   N/A
 48   4                             Status EnhancementAsProxyLazinessInterceptor.status                     N/A
 52   4                                    (object alignment gap)                                           
Instance size: 56 bytes
Space losses: 1 bytes internal + 4 bytes external = 5 bytes total

org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor object internals:
OFF  SZ                               TYPE DESCRIPTION                                             VALUE
  0   8                                    (object header: mark)                                   N/A
  8   4                                    (object header: class)                                  N/A
 12   1                            boolean AbstractInterceptor.allowLoadOutsideTransaction         N/A
 13   3                                    (alignment/padding gap)                                 
 16   4                             String AbstractInterceptor.entityName                          N/A
 20   4   SharedSessionContractImplementor AbstractInterceptor.session                             N/A
 24   4                             String AbstractInterceptor.sessionFactoryUuid                  N/A
 28   4                             Object LazyAttributeLoadingInterceptor.identifier              N/A
 32   4                        Set<String> LazyAttributeLoadingInterceptor.lazyFields              N/A
 36   4                        Set<String> LazyAttributeLoadingInterceptor.initializedLazyFields   N/A
 40   4                        Set<String> LazyAttributeLoadingInterceptor.mutableLazyFields       N/A
 44   4                                    (object alignment gap)                                  
Instance size: 48 bytes
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total

After:

org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor object internals:
OFF  SZ                        TYPE DESCRIPTION                                               VALUE
  0   8                             (object header: mark)                                     N/A
  8   4                             (object header: class)                                    N/A
 12   4   SessionAssociationMarkers AbstractInterceptor.sessionAssociation                    N/A
 16   4                   EntityKey EnhancementAsProxyLazinessInterceptor.entityKey           N/A
 20   4          EntityRelatedState EnhancementAsProxyLazinessInterceptor.meta                N/A
 24   4                 Set<String> EnhancementAsProxyLazinessInterceptor.writtenFieldNames   N/A
 28   4                      Status EnhancementAsProxyLazinessInterceptor.status              N/A
Instance size: 32 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total


org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor object internals:
OFF  SZ                        TYPE DESCRIPTION                                             VALUE
  0   8                             (object header: mark)                                   N/A
  8   4                             (object header: class)                                  N/A
 12   4   SessionAssociationMarkers AbstractInterceptor.sessionAssociation                  N/A
 16   4                      Object LazyAttributeLoadingInterceptor.identifier              N/A
 20   4          EntityRelatedState LazyAttributeLoadingInterceptor.entityMeta              N/A
 24   4                 Set<String> LazyAttributeLoadingInterceptor.initializedLazyFields   N/A
 28   4                             (object alignment gap)                                  
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

This exploration also led to rethink how we model the association of such an interceptor to the current Session, also providing both memory and computational benefits. Code comments hopefully explain this in more detail.

(fully relies on all existing tests)


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


https://hibernate.atlassian.net/browse/HHH-19536

@hibernate-github-bot
Copy link

hibernate-github-bot bot commented Jun 23, 2025

Thanks for your pull request!

This pull request does not follow the contribution rules. Could you have a look?

❌ All commit messages should start with a JIRA issue key matching pattern HHH-\d+
    ↳ Offending commits: [2349f78, 8519a3a]

› This message was automatically generated.

@Sanne Sanne force-pushed the LighterInterceptors branch 3 times, most recently from 2758cb3 to bcdd784 Compare June 26, 2025 21:09
@Sanne Sanne changed the title [Draft ] Lighter interceptors: more efficient initialization and lower memory usage Lighter interceptors: more efficient initialization and lower memory usage Jun 26, 2025
@Sanne Sanne force-pushed the LighterInterceptors branch from bcdd784 to 4c3ea69 Compare June 26, 2025 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant