Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix memory leaks due to retained tagify, sortable or tooltipster instances #17483

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Codas
Copy link
Contributor

@Codas Codas commented Nov 25, 2024

This PR fixes memory leaks in character/npc/hazard/party/kingdom/item sheets and various other places.

Any application currently using Sortable, tooltipster or Tagify is currently leaking memory (some references + the entire detached application dom tree) because these utilities register global event handlers or other global references that survive the application elements being detached from the DOM.

The solution to this to use the respective destroy methods these libraries provide. Either .destroy() on the Sortable or Tagify instances or $(element).tooltipster('destroy') for tooltipster.
This is done by keeping references to the active instances and destroying and nulling them when the application is closed, new event handlers are registered or rule element forms are not used anymore.

The memory profiles in the coming examples were done the following way:

  • Reload foundry
  • perform activity once to trigger any lazy allocations that are done only once for each application
  • trigger manual garbage collection in chrome memory profiler
  • start memory profiling
  • do the activity three more times, each time running manual garbage collection after the activity is performed
  • stop memory profiling

Ideal results are: Three spikes in the allocation that reset to a flat line of exactly the same height as before the spike.

These are the results:

NPC Sheet

before PR
00-npc_sheet_before

after PR
00-npc_sheet_after

Character Sheet

before PR
01-character_sheet_before

after PR

01-character_sheet_after

Hazard Sheet _Note: Hazard has to be in "unlocked" mode for tagify to be instantianted and triggere the memory leak_

before PR
02-hazard_sheet_before

after PR
02-hazard_sheet_after

Kingdom Sheet _Note: I was unable to test this one as I don't have access to the Kingmaker Premium Module._

before PR
N/A
after PR
N/A

Party Sheet

before PR
03-party_sheet_before

after PR
03-party_sheet_after

IWR Editor

before PR
04-iwr_editor_before

after PR
04-iwr_editor_after

Compendium Browser _Note: This requires the compendiom browser to be opened with a tab that has tagify instances. The Equipment tab for example._

before PR
05-compendium_browser_before

after PR
05-compendium_browser_after

Pick a Thing Prompt _Note: TODO describe which thing was picked_

before PR
06-pick_a_thing_before

after PR
06-pick_a_thing_after

Encounter Tracker _Note: This occured whenever the listeners were activated again. For testing, the encounter turn was advanced by one step._

before PR
07-encounter_tracker_before

after PR
07-encounter_tracker_after

Note for Rule Elements: This was tested by creating the rule element for a standalone item, then deleting the rule element again without closing the item sheet. Even closing the item sheet however, memory was not freed.

Rule Element Forms: Actor Traits _Note: TODO - how to test?_

before PR
08-actor_traits_ref_before

after PR
08-actor_traits_ref_after

Rule Element Forms: Aura

before PR
09-aura_ref_before

after PR
09-aura_ref_after

Rule Element Forms: Fast Healing _Note: Type has to be set to "regeneration" for memory leak to trigger_

before PR
10-fast_healing_ref_before

after PR
10-fast_healing_ref_after

Rule Element Forms: Roll Note

before PR
11-roll_note_ref_before

after PR
11-roll_note_ref_after

Campaign Feature

before PR
12-campaign_feat_sheet_before

after PR
12-campaign_feat_sheet_after

Deity Sheet

before PR
13-deity_sheet_before

after PR
13-deity_sheet_after

Feat Sheet

before PR
14-feat_sheet_before

after PR
14-feat_sheet_after

Spell Sheet

before PR
15-spell_sheet_before

*after PR
15-spell_sheet_after

Scene Config Sheet

before PR
16-scene_config_before

after PR
16-scene_config_after

Homebrew Language Settings sheet

before PR
17-homebrew_language_before

after PR
17-homebrew_language_after

Skill Check Prompt Macro

before PR
18-request_check_macro_before

after PR
18-request_check_macro_after

@CarlosFdez
Copy link
Collaborator

CarlosFdez commented Nov 25, 2024

What should we be looking at in the profiler? I will be honest and admit that for larger performance concerns outside of time spent, these finer features of the debugger are lost on me, and it seems like the heap is actually larger now overall. I'd be fine with the easiest to understand guide you are aware of.

Are you aware of the code/known issue/etc for all 3 of these libraries and can you link them? One of them being a leak wouldn't be a surprise, but all 3 is a bit wild. What's the likelihood that these global listeners aren't simply reused for all 3 once registered? Or that its memory that hasn't been gc'd yet? seems you accounted for this with manual gc in the profiler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants