Naninovel memory leaks after end of story
I originally posted in the #support discord channel but for better transparency for my co-workers or even further follow-up from them, let me cross-post and give more issue update here.
This is the code I used to switch from naninovel mode to supergame mode.
Code: Select all
[CommandAlias("supergame")]
public class SwitchToSupergameMode : Command
{
[ParameterAlias("reset")] public BooleanParameter ResetState = true;
public BooleanParameter OnlyCleanUp;
public override async UniTask ExecuteAsync(CancellationToken cancellationToken = default)
{
// 0. Save Naninovel State -- need to resume the reward screen
if (NaninovelSaveManager.instance.AllowSave())
{
NaninovelSaveManager.instance.SaveStateSync();
}
// 1. Disable Naninovel input.
var inputManager = Engine.GetService<IInputManager>();
inputManager.ProcessInput = false;
// 2. Stop script player.
var scriptPlayer = Engine.GetService<IScriptPlayer>();
scriptPlayer.Stop();
// 3. Hide text printer.
var hidePrinter = new HidePrinter();
hidePrinter.ExecuteAsync(cancellationToken).Forget();
// 3.5 wait for save is done then could unload assets
// 3.6 set isreading = false
NaninovelDriver.instance.isReading = false;
// 4. Reset state (if required).
var stateManager = Engine.GetService<IStateManager>();
if (ResetState)
{
await stateManager.ResetStateAsync();
}
SpineCharacterViewController.ClearAssetCache();
// 5. Switch cameras.
bool inNaniTestScene = GameManager.instance.DisableAutoReadNovel;
if (inNaniTestScene)
{
var advCamera = GameObject.Find("Main Camera").GetComponent<Camera>();
advCamera.enabled = true;
UINaninovelStartMenu.instance.Show();
}
else
{
NaninovelDriver.instance.EndStory();
}
var naniCamera = Engine.GetService<ICameraManager>().Camera;
naniCamera.enabled = false;
await Resources.UnloadUnusedAssets();
NaninovelUtility.Log("finish Unity UnloadUnusedAssets 1");
NaninovelUtility.Log("finish @supergame command");
}
}
In the code, I have:
1) Await-ed for all async calls
2) Called Naninovel API
Code: Select all
await stateManager.ResetStateAsync();
to ensure unload Naninovel unused resources
3) Called Unity API
Code: Select all
await Resources.UnloadUnusedAssets();
to unload unused assets as well.
But from the memory profiler, after called this @supergame command and exit from Naninovel mode to supergame mode, the background assets are still in memory, no matter how long I wait. Due to our game designn, We will frequently switch between Naninovel mode vs Supergame mode, and have a lot of different background assets in Naninovel scenes, if the past Naninovel scenes cannot release unused background assets, and per background asset texture2D size is around 6.5MB. Then it would be a lot of memory leaks!
Here's the screenshot from the Unity memory profiler.
https://drive.google.com/file/d/1TnYS8M ... sp=sharing
The first few lines in the screenshot that has 422 Reference count are all Naninovel background assets. And this is the screenshot that after I exit the Naninovel mode. I understand the Texture2D will be GC by Unity, but that assumes the texture reference count is 0 right? If the texture refernece count > 0 then it will never be released by Unity. The reference count is 300400. Some are referred by Naninovel GameStateSlot, Some are Naninovel TextProvider, some are referred by Naninovel scriptable button, Naninovel choiceHandler button, etc. Really weird.
Since I noticed if I never quit the app, then the previous naninovel mode background assets will always in memory even if I am in Supergame mode. But if I quit the app in Supergame mode, those previous background assets will be gone. So I started trying to Destroy and re-init the Naninovel engine on the fly when switching back to Naninovel mode again. But the problem is after calling Engine.Destroy() next time called scriptPlayer.Play() it will have a lot of MissingReferrence Errors, like the ModifyOrthoActor will trying to get the camera from CameraManager "cache", but the destory memory seems not destroy that cache and still refer to the destroyed cameraManager.... So I switch back to fix this memory leaks issue directly..
Overall,
Do you think am I missing anything that could cause these background assets memory leaks?
Any ideas what cause this? Can you explain why the outdated background texture still has 300-400 reference count inside Naninovel Engine?
Could you repro this? If you could, will you fix it?
Many thanks!