Skip to content

Reuse generated entity instantiators from ClassGeneratingEntityInstantiator instances #2446

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

Closed
CallMeSweets opened this issue Sep 8, 2021 · 1 comment
Labels
type: task A general task

Comments

@CallMeSweets
Copy link

CallMeSweets commented Sep 8, 2021

There is a class: ClassGeneratingEntityInstantiator which is responsible for creating the instance of class after loading data object from elasticsearch. I am using the ReactiveCrudRepository to load data from elasticsearch. The flow of the code is that the new instantiator is created when this is a first request.
Then the ReflectUtils is used to load class and create dedicated EntityInstantiator. All already created EntityInstantiator are stored in map which should be avaliable in the next request, but the problem is that the map is empty. Because the map is empty later on is the duplicated of class creation exception what I guess might created a memory leak (metaspace). Everything is ok when i am using database as a store, map is not empty and all EntityInstantiator are remembered.

Fragment of code:

@Override
	public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
			ParameterValueProvider<P> provider) {

		EntityInstantiator instantiator = this.entityInstantiators.get(entity.getTypeInformation());

		if (instantiator == null) {
			instantiator = potentiallyCreateAndRegisterEntityInstantiator(entity);
		}

		return instantiator.createInstance(entity, provider);
	}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 8, 2021
@mp911de
Copy link
Member

mp911de commented Sep 9, 2021

Thanks for reporting the issue. There is an issue within the Elasticsearch module which creates a new instance of EntityInstantiators for each read. See spring-projects/spring-data-elasticsearch#1924.

Generally speaking, ClassGeneratingEntityInstantiator doesn't pollute the meta-space as each generated class has a unique name and within the scope of a single ClassLoader, we must have unique names. When defining another EntityInstantiator class with the same name, the class loader throws an linkage exception and falls back to the reflection variant. That isn't perfect.

ClassGeneratingPropertyAccessorFactory already performs a class presence check and we should do the same for ClassGeneratingEntityInstantiator.

@mp911de mp911de added type: task A general task and removed status: waiting-for-triage An issue we've not yet triaged labels Sep 9, 2021
@mp911de mp911de added this to the 2.4.13 (2020.0.13) milestone Sep 9, 2021
@mp911de mp911de changed the title EntityInstantiator - empty map (entityInstantiators) per request Reuse generated entity instantiators from ClassGeneratingEntityInstantiator instances Sep 9, 2021
@mp911de mp911de closed this as completed in f480550 Sep 9, 2021
mp911de added a commit that referenced this issue Sep 9, 2021
…ntiator` instances.

We now reuse generated ObjectInstantiator classes instead of attempting to redefine classes with the same name. Redefinition leads to LinkageError and thus to the use of reflection-based instantiators and an increased allocation rate due to the failed attempt of class redeclaration.

Closes: #2446.
mp911de added a commit that referenced this issue Sep 9, 2021
…ntiator` instances.

We now reuse generated ObjectInstantiator classes instead of attempting to redefine classes with the same name. Redefinition leads to LinkageError and thus to the use of reflection-based instantiators and an increased allocation rate due to the failed attempt of class redeclaration.

Closes: #2446.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: task A general task
Projects
None yet
Development

No branches or pull requests

3 participants