[1.16.3] Huge memory leak on disconnect/reconnect
ViRb3 opened this issue ยท 4 comments
Environment
Minecraft version: 1.16.3
JEI version: jei-1.16.4-7.6.0.52.jar
Reproduction
- Join a server
- Note minimum used RAM after GC in F3 menu
- Disconnect
- Repeat
Every time you join, the minimum used RAM is increased with about 400MB, depending on how many items are defined in JEI. As you can imagine, this quickly eats up all the allocated RAM and starts severely stuttering, ultimately crashing with OOM.
I took a heap dump via JProfiler and noticed this:
Apparently, a new instance of IngredientFilter
(and RecipeManager
?) is allocated on each join. I tried to trace the incoming references in hopes I will find the source, but there's just too many. If you need any other information from the heap dump, please let me know and I will do my best to provide it.
I can confirm that this issue also happens with a completely fresh Forge instance, with just JEI installed. Each time I join a server or Single Player world, a new IngredientFilter
class is spawned. I am currently sitting at 16 instances.
I was correct for the most part. The root of the problem is that, among others, IngredientFilter
is properly unregistered:
JustEnoughItems/src/main/java/mezz/jei/Internal.java
Lines 95 to 101 in 0c41a86
But not the listeners defined inside it:
JustEnoughItems/src/main/java/mezz/jei/ingredients/IngredientFilter.java
Lines 93 to 101 in 0c41a86
These leftover subscriptions prevent the
IngredientFilter
object from being garbage collected, and results in the memory leak described above.
Now, about the fix. We could mitigate this issue by adding a shutdown hook and removing the listeners there. But this is a very error-prone task, and I can almost guarantee that more listeners will slip in the future. Therefore I propose a general solution, which will fix all of these problems and prevent them in the future. More details will follow in a PR shortly :)