Skip to content

Commit b4024f6

Browse files
committed
Reset EncoderCache after each server resource reload
1 parent 9b7a174 commit b4024f6

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.encoder_cache_leak;
2+
3+
import net.minecraft.core.component.DataComponents;
4+
import net.minecraft.util.EncoderCache;
5+
import org.spongepowered.asm.mixin.Mixin;
6+
import org.spongepowered.asm.mixin.gen.Accessor;
7+
8+
@Mixin(DataComponents.class)
9+
public interface DataComponentsAccessor {
10+
@Accessor("ENCODER_CACHE")
11+
static EncoderCache mfix$getCache() {
12+
throw new AssertionError();
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.encoder_cache_leak;
2+
3+
import com.google.common.cache.LoadingCache;
4+
import net.minecraft.util.EncoderCache;
5+
import org.spongepowered.asm.mixin.Mixin;
6+
import org.spongepowered.asm.mixin.gen.Accessor;
7+
8+
@Mixin(EncoderCache.class)
9+
public interface EncoderCacheAccessor {
10+
@Accessor("cache")
11+
LoadingCache<?, ?> mfix$getCache();
12+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.encoder_cache_leak;
2+
3+
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
4+
import net.minecraft.core.component.DataComponents;
5+
import net.minecraft.server.ReloadableServerResources;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.injection.At;
8+
9+
import java.util.concurrent.CompletableFuture;
10+
11+
@Mixin(ReloadableServerResources.class)
12+
public class ReloadableServerResourcesMixin {
13+
/**
14+
* @author embeddedt
15+
* @reason Some mods (e.g. KubeJS) may provide a custom DynamicOps instance during resource reload. This instance
16+
* can end up being strongly retained by an EncoderCache.Key entry even after the reload finishes. The simplest
17+
* fix is to invalidate all entries of the encoder cache after a server-side resource reload, which should not break
18+
* mods, as the cache is not guaranteed to persist entries for any length of time due to using both a maximum size
19+
* & soft values.
20+
*/
21+
@ModifyReturnValue(method = "loadResources", at = @At("RETURN"))
22+
private static CompletableFuture<ReloadableServerResources> resetEncoderCache(CompletableFuture<ReloadableServerResources> future) {
23+
return future.whenComplete((r, t) -> {
24+
((EncoderCacheAccessor)DataComponentsAccessor.mfix$getCache()).mfix$getCache().invalidateAll();
25+
});
26+
}
27+
}

0 commit comments

Comments
 (0)