Skip to content

Commit 6908f14

Browse files
committed
Mitigation for memory usage from leaked client worlds
1 parent 6fa24ec commit 6908f14

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.embeddedt.modernfix.common.mixin.bugfix.world_leaks;
2+
3+
import net.minecraft.client.Minecraft;
4+
import net.minecraft.client.multiplayer.ClientLevel;
5+
import net.minecraft.world.level.chunk.LevelChunk;
6+
import net.minecraft.world.level.lighting.LevelLightEngine;
7+
import org.embeddedt.modernfix.ModernFix;
8+
import org.jetbrains.annotations.Nullable;
9+
import org.objectweb.asm.Opcodes;
10+
import org.spongepowered.asm.mixin.Mixin;
11+
import org.spongepowered.asm.mixin.Shadow;
12+
import org.spongepowered.asm.mixin.injection.At;
13+
import org.spongepowered.asm.mixin.injection.Inject;
14+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15+
16+
import java.util.concurrent.atomic.AtomicReferenceArray;
17+
18+
@Mixin(Minecraft.class)
19+
public class MinecraftMixin {
20+
@Shadow @Nullable public ClientLevel level;
21+
22+
/**
23+
* To mitigate the effect of leaked client worlds, clear most of the data structures that waste memory.
24+
*/
25+
@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;"))
26+
private void clearLevelDataForLeaks(CallbackInfo ci) {
27+
if(this.level != null) {
28+
try {
29+
AtomicReferenceArray<LevelChunk> chunks = this.level.getChunkSource().storage.chunks;
30+
for(int i = 0; i < chunks.length(); i++) {
31+
chunks.set(i, null);
32+
}
33+
this.level.getChunkSource().lightEngine = new LevelLightEngine(this.level.getChunkSource(), false, false);
34+
// clear BE list otherwise they will hold chunks
35+
this.level.blockEntityList.clear();
36+
} catch(RuntimeException e) {
37+
ModernFix.LOGGER.error("Exception clearing level data", e);
38+
}
39+
}
40+
}
41+
}

common/src/main/resources/modernfix.accesswidener

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
accessWidener v2 named
22

3+
accessible field net/minecraft/client/multiplayer/ClientChunkCache storage Lnet/minecraft/client/multiplayer/ClientChunkCache$Storage;
4+
accessible field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet/minecraft/world/level/lighting/LevelLightEngine;
5+
mutable field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet/minecraft/world/level/lighting/LevelLightEngine;
6+
accessible class net/minecraft/client/multiplayer/ClientChunkCache$Storage
7+
accessible field net/minecraft/client/multiplayer/ClientChunkCache$Storage chunks Ljava/util/concurrent/atomic/AtomicReferenceArray;
8+
39
accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType
410
accessible method net/minecraft/client/renderer/RenderType$CompositeRenderType <init> (Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$CompositeState;)V
511
accessible method net/minecraft/nbt/CompoundTag <init> (Ljava/util/Map;)V

0 commit comments

Comments
 (0)