From dcb72dfa6275b40b7661245bd3b257df88401da2 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:25:23 -0400 Subject: [PATCH 1/4] Add more links to Mod Menu --- fabric/src/main/resources/fabric.mod.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index e6525d26..7ea779c1 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -14,6 +14,15 @@ }, "license": "LGPL-3.0", "icon": "icon.png", + "custom": { + "modmenu": { + "links": { + "modmenu.kofi": "https://ko-fi.com/embeddedt", + "modmenu.github_releases": "https://github.com/embeddedt/ModernFix/releases", + "modmenu.curseforge": "https://www.curseforge.com/minecraft/mc-mods/modernfix" + } + } + }, "environment": "*", "entrypoints": { "main": [ From 6fa24ec171857aa0ba97e654e916a5edc5514185 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 12:23:43 -0400 Subject: [PATCH 2/4] Change CanonizingStringMap to use weak interner --- .../java/org/embeddedt/modernfix/util/CanonizingStringMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java index 845fbb1e..015e74a4 100644 --- a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java @@ -12,7 +12,7 @@ import java.util.Map; * Replacement backing map for CompoundTags that interns keys. */ public class CanonizingStringMap extends HashMap { - private static final Interner KEY_INTERNER = Interners.newStrongInterner(); + private static final Interner KEY_INTERNER = Interners.newWeakInterner(); private static String intern(String key) { return key != null ? KEY_INTERNER.intern(key) : null; From 6908f1490560582ee90918a167298946a629e6c7 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 13:04:04 -0400 Subject: [PATCH 3/4] Mitigation for memory usage from leaked client worlds --- .../bugfix/world_leaks/MinecraftMixin.java | 41 +++++++++++++++++++ .../main/resources/modernfix.accesswidener | 6 +++ 2 files changed, 47 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java new file mode 100644 index 00000000..d3708ff8 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java @@ -0,0 +1,41 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.world_leaks; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.lighting.LevelLightEngine; +import org.embeddedt.modernfix.ModernFix; +import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.concurrent.atomic.AtomicReferenceArray; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + @Shadow @Nullable public ClientLevel level; + + /** + * To mitigate the effect of leaked client worlds, clear most of the data structures that waste memory. + */ + @Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/client/Minecraft;level:Lnet/minecraft/client/multiplayer/ClientLevel;")) + private void clearLevelDataForLeaks(CallbackInfo ci) { + if(this.level != null) { + try { + AtomicReferenceArray chunks = this.level.getChunkSource().storage.chunks; + for(int i = 0; i < chunks.length(); i++) { + chunks.set(i, null); + } + this.level.getChunkSource().lightEngine = new LevelLightEngine(this.level.getChunkSource(), false, false); + // clear BE list otherwise they will hold chunks + this.level.blockEntityList.clear(); + } catch(RuntimeException e) { + ModernFix.LOGGER.error("Exception clearing level data", e); + } + } + } +} diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index aa5fa80f..3db3ffae 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -1,5 +1,11 @@ accessWidener v2 named +accessible field net/minecraft/client/multiplayer/ClientChunkCache storage Lnet/minecraft/client/multiplayer/ClientChunkCache$Storage; +accessible field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet/minecraft/world/level/lighting/LevelLightEngine; +mutable field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet/minecraft/world/level/lighting/LevelLightEngine; +accessible class net/minecraft/client/multiplayer/ClientChunkCache$Storage +accessible field net/minecraft/client/multiplayer/ClientChunkCache$Storage chunks Ljava/util/concurrent/atomic/AtomicReferenceArray; + accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType accessible method net/minecraft/client/renderer/RenderType$CompositeRenderType (Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$CompositeState;)V accessible method net/minecraft/nbt/CompoundTag (Ljava/util/Map;)V From ed0460747cd64b8d1047d6bdbabc00551ae0541a Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 13:08:42 -0400 Subject: [PATCH 4/4] Update world leak patch to 1.18 --- .../common/mixin/bugfix/world_leaks/MinecraftMixin.java | 2 +- common/src/main/resources/modernfix.accesswidener | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java index d3708ff8..e4f0fa57 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java @@ -32,7 +32,7 @@ public class MinecraftMixin { } this.level.getChunkSource().lightEngine = new LevelLightEngine(this.level.getChunkSource(), false, false); // clear BE list otherwise they will hold chunks - this.level.blockEntityList.clear(); + this.level.blockEntityTickers.clear(); } catch(RuntimeException e) { ModernFix.LOGGER.error("Exception clearing level data", e); } diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index e0e15597..db75195f 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -6,6 +6,8 @@ mutable field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet accessible class net/minecraft/client/multiplayer/ClientChunkCache$Storage accessible field net/minecraft/client/multiplayer/ClientChunkCache$Storage chunks Ljava/util/concurrent/atomic/AtomicReferenceArray; +accessible field net/minecraft/world/level/Level blockEntityTickers Ljava/util/List; + accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType accessible method net/minecraft/nbt/CompoundTag (Ljava/util/Map;)V