Frequent calls to Slimefun API during chunk regeneration cause main thread lag
Expected behavior
Optimize block regeneration module
Observed/Actual behavior
When BentoBox performs block regeneration (such as resetting an island), frequent calls to BlockStorage.clearBlockInfo() can cause the main thread to freeze. The stack trace shows that the performance bottleneck is in the ConcurrentHashMap.get() and String.equals() calls of BlockDataController.getBlockData(), which is suspected to be caused by the hash table being too large or the key value matching being inefficient, causing the main thread to be blocked.
Steps/models to reproduce
Use BentoBox to create an island world Place Slimefun machines/blocks in the island Trigger island reset or chunk regeneration Observe main thread freeze and Server has not responded warning
BentoBox version
[20:03:43 INFO]: Running on: PAPER 1.21.4. [20:03:43 INFO]: (1.21.4-DEV-71da771 (MC: 1.21.4)) [20:03:43 INFO]: BentoBox version: 3.2.3 [20:03:43 INFO]: Database type: JSON [20:03:43 INFO]: Loaded worlds: [20:03:43 INFO]: bskyblock_world (BSkyBlock): Overworld, Nether, The End [20:03:43 INFO]: Loaded addons: [20:03:43 INFO]: Biomes 2.2.0 (ENABLED) [20:03:43 INFO]: Border 4.4.2 (ENABLED) [20:03:43 INFO]: BSkyBlock 1.19.0 (ENABLED) [20:03:43 INFO]: Challenges 1.4.0 (ENABLED) [20:03:43 INFO]: ControlPanel 1.14.0 (ENABLED) [20:03:43 INFO]: DimensionalTrees 1.8.0 (ENABLED) [20:03:43 INFO]: Level 2.17.1 (ENABLED) [20:03:43 INFO]: Limits 1.26.0 (ENABLED) [20:03:43 INFO]: MagicCobblestoneGenerator 2.6.0 (ENABLED) [20:03:43 INFO]: Warps 1.16.0 (ENABLED)
Plugin list
[20:04:09 INFO]: Paper Plugins: (1): [20:04:09 INFO]: - CrazyCrates [20:04:09 INFO]: Bukkit Plugins: (37): [20:04:09 INFO]: - BentoBox, BentoBox-Biomes, BentoBox-BSkyBlock, BentoBox-Challenges, BentoBox-Level, BentoBox-Limits, BentoBox-MagicCobblestoneGenerator, BentoBox-Warps, BlockParticles, CoreProtect [20:04:09 INFO]: CrazyAuctions, eco, EcoEnchants, Essentials, EssentialsSpawn, ExoticGarden, ExtraHeads, FastAsyncWorldEdit, GuizhanLibPlugin, LagFixer [20:04:09 INFO]: libreforge, LuckPerms, MineResetLite, PlaceholderAPI, PluginPortal, ProtocolLib, ShopGUIPlus, SilkSpawners_v2, SkinsRestorer, Slimefun [20:04:09 INFO]: TrMenu, Vault, ViaBackwards, ViaRewind, ViaRewind-Legacy-Support, ViaVersion, WorldGuard
Other
Error log
[19:36:25 ERROR]: The server has not responded for 10 seconds! Creating thread dump
[19:36:25 ERROR]: ------------------------------
[19:36:25 ERROR]: Server thread dump (Look for plugins here before reporting to Leaf!):
[19:36:25 ERROR]: ------------------------------
[19:36:25 ERROR]: Current Thread: Server thread
[19:36:25 ERROR]: PID: 50 | Suspended: false | Native: false | State: RUNNABLE
[19:36:25 ERROR]: Stack:
[19:36:25 ERROR]: java.base/java.lang.String.regionMatchesInternal(String.java:2935)
[19:36:25 ERROR]: java.base/java.lang.String.equals(String.java:2540)
[19:36:25 ERROR]: java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:945)
[19:36:25 ERROR]: Slimefun-f1d7ce2-Beta.jar//com.xzavier0722.mc.plugin.slimefun4.storage.controller.BlockDataController.getChunkDataCache(BlockDataController.java:1290)
[19:36:25 ERROR]: Slimefun-f1d7ce2-Beta.jar//com.xzavier0722.mc.plugin.slimefun4.storage.controller.BlockDataController.getBlockData(BlockDataController.java:434)
[19:36:25 ERROR]: Slimefun-f1d7ce2-Beta.jar//me.mrCookieSlime.Slimefun.api.BlockStorage.getBlockData(BlockStorage.java:66)
[19:36:25 ERROR]: Slimefun-f1d7ce2-Beta.jar//me.mrCookieSlime.Slimefun.api.BlockStorage.hasBlockInfo(BlockStorage.java:114)
[19:36:25 ERROR]: BentoBox-3.2.3.jar//world.bentobox.bentobox.hooks.SlimefunHook.clearBlockInfo(SlimefunHook.java:31)
[19:36:25 ERROR]: BentoBox-3.2.3.jar//world.bentobox.bentobox.nms.CopyWorldRegenerator.lambda$copyChunkDataToChunk$19(CopyWorldRegenerator.java:428)
[19:36:25 ERROR]: java.base/java.util.Optional.ifPresent(Optional.java:178)
[19:36:25 ERROR]: BentoBox-3.2.3.jar//world.bentobox.bentobox.nms.CopyWorldRegenerator.copyChunkDataToChunk(CopyWorldRegenerator.java:428)
[19:36:25 ERROR]: BentoBox-3.2.3.jar//world.bentobox.bentobox.nms.CopyWorldRegenerator.lambda$regenerateChunk$16(CopyWorldRegenerator.java:398)
[19:36:25 ERROR]: java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:684)
[19:36:25 ERROR]: java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:662)
[19:36:25 ERROR]: java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2200)
[19:36:25 ERROR]: BentoBox-3.2.3.jar//world.bentobox.bentobox.nms.CopyWorldRegenerator.regenerateChunk(CopyWorldRegenerator.java:391)
[19:36:25 ERROR]: BentoBox-3.2.3.jar//world.bentobox.bentobox.nms.CopyWorldRegenerator$2.run(CopyWorldRegenerator.java:358)
[19:36:25 ERROR]: org.bukkit.craftbukkit.scheduler.CraftTask.run(CraftTask.java:78)
[19:36:25 ERROR]: org.bukkit.craftbukkit.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:474)
[19:36:25 ERROR]: net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1676)
[19:36:25 ERROR]: net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1556)
[19:36:25 ERROR]: net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1274)
[19:36:25 ERROR]: net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:298)
[19:36:25 ERROR]: java.base/java.lang.Thread.run(Thread.java:1595)
[19:36:25 ERROR]: ------------------------------
[19:36:25 ERROR]: --- DO NOT REPORT THIS TO PAPER - If you think this is a Leaf bug, please report it at https://github.com/Winds-Studio/Leaf/issues - THIS IS NOT A PAPER BUG OR CRASH ---
[19:36:25 ERROR]: ------------------------------
In addition to this, in blueprint mode, copying blocks is very inefficient Usually,resetting the island will cause a serious drop in TPS
The deletion of blocks is a difficult task and for SlimeFun, right now, we have to go through every possible location and ask it to delete any block that is there. There is currently no alternative, however, maybe there could be in the future. As you are running SlimeFun, this has to occur.
The process of island deletion is done in a pseudo async way by doing a little bit at a time, repeatedly, over a longer period of time. If you are seeing this lag, then I recommend you try and reduce the amount of blocks that are deleted at a time. In the BentoBox config.yml you can reduce the default number of chunks deleted in one go to be less than the default 100:
delete-speed: 100
You can also try and use slow deletion:
slow-deletion: true
You may also be able to use Regionator, although I don't know if it works with SlimeFun. https://docs.bentobox.world/en/latest/gamemodes/Boxed/#using-regionerator
You wrote:
In addition to this, in blueprint mode, copying blocks is very inefficient
Yes, if you are doing copy and paste, locally, then it has to use Bukkit API, which is slow. You can try and play with the paste speed setting too:
# Number of blocks to paste per tick when pasting blueprints.
# Smaller values will help reduce noticeable lag but will make pasting take slightly longer.
# On the contrary, greater values will make pasting take less time, but this benefit is quickly severely impacted by the
# resulting amount of chunks that must be loaded to fulfill the process, which often causes the server to hang out.
paste-speed: 64
Good luck!