Duplicate Variable Invalidate Listeners registered when updating part offset
Yamazak-mc opened this issue Ā· 1 comments
Issue type:
- š Performance issue
Description:
When placing a variable card that depends on other variable IDs into a part offset slot, duplicate listeners are registered on the dependency variableās invalidateListeners. Over long runtimes this accumulates and eventually consumes heap memory.
Steps to reproduce the problem:
- Prepare a part with an offset upgrade.
- Prepare these variable cards:
- ID 1:
Long(1) - ID 2:
Cast Long to Integer(variable IDs:[1])
- ID 1:
- Insert the card ID 2 into the partās offset slot.
- Remove the card from the slot and re-insert it.
At step 3 the invalidateListener registered on ID 1 is not cleared; at step 4 an additional (duplicate) listener gets registered.
In many cases, this might not cause issues because once a variable is evaluated, I assume its listeners are all cleared. However, when duplicate listeners accumulate on constants like Long(1), memory usage can grow over time.
In my actual gameplay
My friend and I were playing a modpack where we had a variable card in the offset slot with an expression like:
offset = (Current time % N) + 1
After running the world for several hours we started to see lag spikes. Turns out Integer 1 had accumulated tons of duplicate listeners, which eventually filled up several GB of heap.
Analysis
The containsKey check in the part offset handler is failing every time because the variable argument is a different LazyExpression instance on each call ā even though the logical expression id is the same.
Relevant code:
I'm very new to Minecraft modding, so unfortunately I couldn't figure out a good solution to this problem.
Versions:
I tested the following versions, and the issue occurs in both:
1.20.1
- This mod: 1.20.1-1.27.6
- Cyclops Core: 1.20.1-1.20.1
- Minecraft: 1.20.1
- Forge: 47.4.0
1.21.1
- This mod: 1.21.1-neoforge-1.27.9
- Cyclops Core: 1.21.1-neoforge-1.26.2
- Minecraft: 1.21.1
- Neoforge: 21.1.209
