From 99771a275e908f9fbfda03f6998d1437449e4f5a Mon Sep 17 00:00:00 2001 From: Lignium Date: Mon, 16 May 2022 18:06:26 +0300 Subject: [PATCH 1/4] Fix block entity memory leak --- .../common/mixin/core/server/level/ServerLevelMixin.java | 9 +++++++++ .../common/mixin/core/world/level/LevelMixin.java | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java index c2d18289bb3..b9de40754a5 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java @@ -441,6 +441,15 @@ public void save(@Nullable final ProgressListener progress, final boolean flush, this.impl$recentTickTimes[this.shadow$getServer().getTickCount() % 100] = postTickTime - this.impl$preTickTime; } + @Inject(method = "tick", at = @At("RETURN")) + private void impl$unloadBlockEntities(final BooleanSupplier param0, final CallbackInfo ci) { + if (!this.blockEntitiesToUnload.isEmpty()) { + this.tickableBlockEntities.removeAll(this.blockEntitiesToUnload); + this.blockEntityList.removeAll(this.blockEntitiesToUnload); + this.blockEntitiesToUnload.clear(); + } + } + private void impl$setWorldOnBorder() { ((WorldBorderBridge) this.shadow$getWorldBorder()).bridge$setAssociatedWorld(this.bridge$getKey()); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java index 9f971e60b70..3d26ffe4a43 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java @@ -66,6 +66,7 @@ import org.spongepowered.common.util.DataUtil; import org.spongepowered.math.vector.Vector3d; +import java.util.List; import java.util.function.Predicate; @Mixin(net.minecraft.world.level.Level.class) @@ -77,6 +78,9 @@ public abstract class LevelMixin implements LevelBridge, LevelAccessor { @Shadow protected float rainLevel; @Shadow protected float oThunderLevel; @Shadow protected float thunderLevel; + @Shadow @Final public List blockEntityList; + @Shadow @Final public List tickableBlockEntities; + @Shadow @Final protected List blockEntitiesToUnload; @Shadow public abstract LevelData shadow$getLevelData(); @Shadow public abstract void shadow$updateSkyBrightness(); From eb3496ff453be8e2f432e831d365c737a3b0d455 Mon Sep 17 00:00:00 2001 From: Lignium Date: Tue, 17 May 2022 23:03:02 +0300 Subject: [PATCH 2/4] Add check of empty time --- .../common/mixin/core/server/level/ServerLevelMixin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java index b9de40754a5..427173a397f 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java @@ -128,6 +128,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel // @formatter:off @Shadow @Final private ServerLevelData serverLevelData; + @Shadow private int emptyTime; @Shadow @Nonnull public abstract MinecraftServer shadow$getServer(); @Shadow protected abstract void shadow$saveLevelData(); @@ -443,7 +444,7 @@ public void save(@Nullable final ProgressListener progress, final boolean flush, @Inject(method = "tick", at = @At("RETURN")) private void impl$unloadBlockEntities(final BooleanSupplier param0, final CallbackInfo ci) { - if (!this.blockEntitiesToUnload.isEmpty()) { + if (this.emptyTime >= 300 && !this.blockEntitiesToUnload.isEmpty()) { this.tickableBlockEntities.removeAll(this.blockEntitiesToUnload); this.blockEntityList.removeAll(this.blockEntitiesToUnload); this.blockEntitiesToUnload.clear(); From 5694a25f990598099609915a1046bd3ec6b9572b Mon Sep 17 00:00:00 2001 From: Lignium Date: Wed, 18 May 2022 18:02:57 +0300 Subject: [PATCH 3/4] Move inject point --- .../mixin/core/server/level/ServerLevelMixin.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java index 427173a397f..cce86326eb4 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java @@ -55,6 +55,7 @@ import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; +import org.objectweb.asm.Opcodes; import org.spongepowered.api.ResourceKey; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; @@ -442,8 +443,18 @@ public void save(@Nullable final ProgressListener progress, final boolean flush, this.impl$recentTickTimes[this.shadow$getServer().getTickCount() % 100] = postTickTime - this.impl$preTickTime; } - @Inject(method = "tick", at = @At("RETURN")) + @Inject( + method = "tick", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/server/level/ServerLevel;emptyTime:I", + opcode = Opcodes.PUTFIELD, + shift = At.Shift.AFTER + ) + ) private void impl$unloadBlockEntities(final BooleanSupplier param0, final CallbackInfo ci) { + // This code fixes block entity memory leak + // https://github.com/SpongePowered/Sponge/pull/3689 if (this.emptyTime >= 300 && !this.blockEntitiesToUnload.isEmpty()) { this.tickableBlockEntities.removeAll(this.blockEntitiesToUnload); this.blockEntityList.removeAll(this.blockEntitiesToUnload); From f73cc5ce74998fa423152856a846288c064369fb Mon Sep 17 00:00:00 2001 From: Lignium Date: Sat, 20 Aug 2022 08:58:40 +0300 Subject: [PATCH 4/4] Bump SpongeAPI --- SpongeAPI | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SpongeAPI b/SpongeAPI index d6fb407d5b6..bdd66ef4873 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit d6fb407d5b667ccaf559e5b9aab8d7028c4f0508 +Subproject commit bdd66ef4873c8275cdf075064fa2d08989262923