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

GameEvents related memory leaks #718

Open
gotmachine opened this issue Jun 29, 2022 · 1 comment
Open

GameEvents related memory leaks #718

gotmachine opened this issue Jun 29, 2022 · 1 comment

Comments

@gotmachine
Copy link

gotmachine commented Jun 29, 2022

I've been doing some work in KSPCF to tackle KSP memory leaks.

Turns out that the vast majority of memory leaks are caused by objects subscribing to GameEvents and never removing them, causing those objects and anything they reference to never be garbage collected.

I've implemented some mechanisms in KSPCF to automatically clean up such leaks when they originate from destroyed instances of UnityEngine.Object derivatives (this notably covers PartModule, VesselModule, KSPAddon and KSPScenario derivatives).

However, there is no way to do such a thing for regular classes, so I've also implemented some debugging tools that allow to detect those leaks.

GameEvents related leaks are not only an issue from a memory standpoint.
All the dead or duplicate delegates are still called, which :

  1. Slows down overall event processing
  2. Can cause hard to track down issues by executing code on instances that are not supposed to exist anymore.

While casually testing KSPCF on an install with CC installed, I found the following GameEvents leaks :

UnityEngine.Object derivatives leaks :

Removed a onGUIMessageSystemReady GameEvents callback owned by a destroyed ContractConfigurator.ScienceReporter instance
Removed a OnScienceRecieved GameEvents callback owned by a destroyed ContractConfigurator.ScienceReporter instance

Other classes leaks :

- "onVesselRenamed"
  - ContractConfigurator:TitleTracker - Subscriptions : 232/348 (last/now)
- "OnMapViewFiltersModified"
  - ContractConfigurator:OrbitGenerator - Subscriptions : 16/22 (last/now)
- "Contract.ParameterChange"
  - ContractConfigurator:TitleTracker - Subscriptions : 232/348 (last/now)

I didn't actually check the CC code for other cases, so keep in mind that there might be false positives in that list. I also didn't do extensive tests, so it is quite possible I missed other leaks.

The TitleTracker class related leaks are quite severe, with 200+ delegates leaked per scene switch in a game with not a lot going on. The pattern of removing GameEvents in a finalizer doesn't work, as the GameEvent subscription will prevent the object from ever be garbage collected in the first place :

~TitleTracker()
{
GameEvents.Contract.onParameterChange.Remove(new EventData<Contract, ContractParameter>.OnEvent(OnParameterChange));
GameEvents.onVesselRename.Remove(new EventData<GameEvents.HostedFromToAction<Vessel, string>>.OnEvent(OnVesselRename));
}

siimav added a commit to KSP-RO/ContractConfigurator that referenced this issue Jul 2, 2022
@siimav
Copy link

siimav commented Jul 2, 2022

KSP-RO fork should have a fix for all the leaks mentioned above + some additional ones.

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

No branches or pull requests

2 participants