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:
- Create a new world.
- 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.
- Pause the chunk generation before Minecraft crashes with OutOfMemoryError.
- Create a heapdump using Spark, with the --run-gc-before flag preferably.
- 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.
Created Issue:
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 confirm that and 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:
- Create a new world.
- 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.
- Pause the chunk generation before Minecraft crashes with OutOfMemoryError.
- Create a heapdump using Spark, with the --run-gc-before flag preferably.
- Inspect the heapdump and see where all the retained memory is.
relates to
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 confirm that
andremove 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:
- Create a new world.
- 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.
- Pause the chunk generation before Minecraft crashes with OutOfMemoryError.
- Create a heapdump using Spark, with the --run-gc-before flag preferably.
- Inspect the heapdump and see where all the retained memory is.
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:
- Create a new world.
- 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.
- Pause the chunk generation before Minecraft crashes with OutOfMemoryError.
- Create a heapdump using Spark, with the --run-gc-before flag preferably.
- Inspect the heapdump and see where all the retained memory is.
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:
- Create a new world.
- 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.
- Pause the chunk generation before Minecraft crashes with OutOfMemoryError.
- Create a heapdump using Spark, with the --run-gc-before flag preferably.
- 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.
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