Clear ObjectHolder Throwable fields after registry events fire
This commit is contained in:
parent
61af88a2ab
commit
f36a8f4266
|
|
@ -18,6 +18,7 @@ import org.apache.logging.log4j.Logger;
|
|||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||
import org.embeddedt.modernfix.entity.EntityDataIDSyncHandler;
|
||||
import org.embeddedt.modernfix.packet.PacketHandler;
|
||||
import org.embeddedt.modernfix.registry.ObjectHolderClearer;
|
||||
import org.embeddedt.modernfix.structure.AsyncLocator;
|
||||
import org.embeddedt.modernfix.util.KubeUtil;
|
||||
|
||||
|
|
@ -91,7 +92,7 @@ public class ModernFix {
|
|||
ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.COMMON_SETUP, "modernfix.no_lazydfu"));
|
||||
});
|
||||
}
|
||||
|
||||
ObjectHolderClearer.clearThrowables();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package org.embeddedt.modernfix.registry;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
import net.minecraftforge.registries.ObjectHolderRegistry;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ObjectHolderClearer {
|
||||
/**
|
||||
* Many of the built-in Forge holders needlessly hold on to an exception.
|
||||
*/
|
||||
public static void clearThrowables() {
|
||||
Set<Consumer<Predicate<ResourceLocation>>> holders = ObfuscationReflectionHelper.getPrivateValue(ObjectHolderRegistry.class, null, "objectHolders");
|
||||
if(holders != null) {
|
||||
int numCleared = 0;
|
||||
HashMap<Class<?>, Field> throwableField = new HashMap<>();
|
||||
Throwable singletonThrowable = new Throwable("[This stacktrace was cleared to save memory]");
|
||||
try {
|
||||
for(Consumer<Predicate<ResourceLocation>> holder : holders) {
|
||||
Field target = throwableField.computeIfAbsent(holder.getClass(), clz -> {
|
||||
Field[] clzFields = clz.getDeclaredFields();
|
||||
for(Field f : clzFields) {
|
||||
if(Throwable.class.isAssignableFrom(f.getType())) {
|
||||
f.setAccessible(true);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
if(target != null) {
|
||||
target.set(holder, singletonThrowable);
|
||||
numCleared++;
|
||||
}
|
||||
}
|
||||
} catch(RuntimeException | ReflectiveOperationException | NoClassDefFoundError ignored) {
|
||||
}
|
||||
ModernFix.LOGGER.debug("Cleared " + numCleared + " object holder stacktrace references");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user