clean guice caches after creating injectors so it will take less memory
This commit is contained in:
parent
343c80b100
commit
fb35b1c993
|
@ -19,10 +19,12 @@
|
|||
|
||||
package org.elasticsearch.common.inject;
|
||||
|
||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||
import org.elasticsearch.common.collect.Sets;
|
||||
import org.elasticsearch.common.inject.matcher.Matcher;
|
||||
import org.elasticsearch.common.inject.name.Names;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -220,4 +222,62 @@ public class Injectors {
|
|||
public static void close(Injector injector) {
|
||||
|
||||
}
|
||||
|
||||
public static void cleanCaches(Injector injector) {
|
||||
// clean blacklist, it becomes really big, and it can always get regenerated if needed
|
||||
try {
|
||||
Field stateField = injector.getClass().getDeclaredField("state");
|
||||
stateField.setAccessible(true);
|
||||
Object state = stateField.get(injector);
|
||||
if (state.getClass().getName().contains("InheritingState")) {
|
||||
Field blacklistedKeysField = state.getClass().getDeclaredField("blacklistedKeys");
|
||||
blacklistedKeysField.setAccessible(true);
|
||||
Object blacklistedKeys = blacklistedKeysField.get(state);
|
||||
Field backingSetField = blacklistedKeys.getClass().getDeclaredField("backingSet");
|
||||
backingSetField.setAccessible(true);
|
||||
((Set) backingSetField.get(blacklistedKeys)).clear();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ElasticSearchIllegalStateException("Failed to clear state from injector", e);
|
||||
}
|
||||
|
||||
// clean constructors cache
|
||||
try {
|
||||
Field constructorsField = injector.getClass().getDeclaredField("constructors");
|
||||
constructorsField.setAccessible(true);
|
||||
Object constructors = constructorsField.get(injector);
|
||||
|
||||
Field cacheField = constructors.getClass().getDeclaredField("cache");
|
||||
cacheField.setAccessible(true);
|
||||
Object cache = cacheField.get(constructors);
|
||||
|
||||
Field delegateField = cache.getClass().getSuperclass().getDeclaredField("delegate");
|
||||
delegateField.setAccessible(true);
|
||||
((Map) delegateField.get(cache)).clear();
|
||||
} catch (Exception e) {
|
||||
throw new ElasticSearchIllegalStateException("Failed to clear constructors cache from injector", e);
|
||||
}
|
||||
|
||||
// clean method cache
|
||||
try {
|
||||
Field membersField = injector.getClass().getDeclaredField("membersInjectorStore");
|
||||
membersField.setAccessible(true);
|
||||
Object members = membersField.get(injector);
|
||||
if (members != null) {
|
||||
Field cacheField = members.getClass().getDeclaredField("cache");
|
||||
cacheField.setAccessible(true);
|
||||
Object cache = cacheField.get(members);
|
||||
|
||||
Field delegateField = cache.getClass().getSuperclass().getDeclaredField("delegate");
|
||||
delegateField.setAccessible(true);
|
||||
((Map) delegateField.get(cache)).clear();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ElasticSearchIllegalStateException("Failed to clear constructors cache from injector", e);
|
||||
}
|
||||
|
||||
if (injector.getParent() != null) {
|
||||
cleanCaches(injector.getParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,11 +55,15 @@ public class ModulesBuilder implements Iterable<Module> {
|
|||
|
||||
public Injector createInjector() {
|
||||
Modules.processModules(modules);
|
||||
return Guice.createInjector(modules);
|
||||
Injector injector = Guice.createInjector(modules);
|
||||
Injectors.cleanCaches(injector);
|
||||
return injector;
|
||||
}
|
||||
|
||||
public Injector createChildInjector(Injector injector) {
|
||||
Modules.processModules(modules);
|
||||
return injector.createChildInjector(modules);
|
||||
Injector childInjector = injector.createChildInjector(modules);
|
||||
Injectors.cleanCaches(childInjector);
|
||||
return childInjector;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue