Skip to content

Commit 33d27ff

Browse files
committed
Fix memory leak on Fabric from models being saved to the vanilla map
1 parent ad948f0 commit 33d27ff

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
9898
private Cache<ResourceLocation, UnbakedModel> loadedModels;
9999

100100
private HashMap<ResourceLocation, UnbakedModel> smallLoadingCache = new HashMap<>();
101+
private Map<ResourceLocation, UnbakedModel> vanillaUnbakedStorage;
101102

102103
private boolean inTextureGatheringPass;
103104

@@ -121,11 +122,11 @@ private void replaceTopLevelBakedModels(ProfilerFiller filler, String s) {
121122
.softValues()
122123
.build();
123124
// temporarily replace this map to capture models into the small loading cache
124-
Map<ResourceLocation, UnbakedModel> oldMap = this.unbakedCache;
125+
vanillaUnbakedStorage = this.unbakedCache;
125126
this.unbakedCache = new ForwardingMap<ResourceLocation, UnbakedModel>() {
126127
@Override
127128
protected Map<ResourceLocation, UnbakedModel> delegate() {
128-
return oldMap;
129+
return vanillaUnbakedStorage;
129130
}
130131

131132
@Override
@@ -313,6 +314,31 @@ public UnbakedModel put(ResourceLocation key, UnbakedModel value) {
313314
ModernFix.LOGGER.info("Early model bake took {}", watch);
314315
ModernFix.LOGGER.info("{} unbaked models, {} baked models loaded permanently", this.unbakedCache.size(), this.bakedCache.size());
315316
this.unbakedCache = new LayeredForwardingMap<>(new Map[] { this.unbakedCache, mutableBackingMap });
317+
// prevent writes from hitting the vanilla map, which prevents GC of models
318+
Map<ResourceLocation, UnbakedModel> oldVanillaStorage = vanillaUnbakedStorage;
319+
vanillaUnbakedStorage = new ForwardingMap<ResourceLocation, UnbakedModel>() {
320+
@Override
321+
protected Map<ResourceLocation, UnbakedModel> delegate() {
322+
return oldVanillaStorage;
323+
}
324+
325+
@Override
326+
public UnbakedModel put(ResourceLocation key, UnbakedModel value) {
327+
UnbakedModel old = get(key);
328+
if(old != null)
329+
remove(key);
330+
return old;
331+
}
332+
333+
@Override
334+
public void putAll(Map<? extends ResourceLocation, ? extends UnbakedModel> map) {
335+
336+
}
337+
338+
@Override
339+
public void clear() {
340+
}
341+
};
316342
this.bakedTopLevelModels = new DynamicBakedModelProvider((ModelBakery)(Object)this, bakedCache);
317343
if(this.bakedMissingModel != null)
318344
((DynamicBakedModelProvider)this.bakedTopLevelModels).setMissingModel(this.bakedMissingModel);

0 commit comments

Comments
 (0)