mojira.dev
MC-272673

Block entity tickers memory leak in Level

At least present in 1.18 as well from the tests I made.

Explanations

There is a list of *BlockEntityTicker* in net.minecraft.world.level.Level that doesn't update itself correctly when chunks that didn't tick once are unloaded. Since a Block entity ticker have to be ticked at least once in order to put itself to a "removed" mode, the Level that will iterate through all of its block entity tickers won't be able to confirm that nor remove them.

This situation can make a Level accumulate more and more block entity tickers that take more and more memory as it goes. We can especially observe this behavior when generating a large portion of chunks without ticking them (as in chunk pre-generation).

Fixing this issue can very easily be done, as simple as removing from the list of its corresponding Level all block entity tickers of a chunk about to be unloaded.

Recreating the memory leak

The simplest way to check that is to create a heapdump after generating loads of chunks using the Chunky and Spark mods:

  1. Create a new world.

  2. Launch a chunk generation task in the Overworld and in the Nether using Chunky. I would say more than 1000000 chunks, but really depends on how much RAM you assigned to Minecraft.

  3. Pause the chunk generation before Minecraft crashes with OutOfMemoryError.

  4. Create a heapdump using Spark, with the --run-gc-before flag preferably.

  5. Inspect the heapdump and see where all the retained memory is.

 

You can also find a heapdump of my own here if you don't want to bother with the whole process.

 

Linked issues

Comments 2

Can you confirm that you are still able to reproduce this issue?

As of 1.21.3 yes, although the problem have deviated to CompoundTag classes being retained (the pending version of BlockEntities yet to be loaded) instead

Juloos

(Unassigned)

Plausible

Platform

Important

Performance

1.20.6

Retrieved