diff options
-rw-r--r-- | docs/release-notes.md | 2 | ||||
-rw-r--r-- | src/SMAPI/Framework/ContentManagers/BaseContentManager.cs | 8 |
2 files changed, 10 insertions, 0 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md index 0ce79d9b..9ac95d86 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -9,6 +9,8 @@ * The 'skipped mods' list now shows broken dependencies first, so it's easier to see which ones to fix first. * Fixed compatibility with Linux Mint 18 (thanks to techge!) and Arch Linux. * Fixed compatibility with Linux systems which have libhybris-utils installed. + * Fixed memory leak when repeatedly loading a save and returning to title. + * Fixed memory leak when mods reload assets. * Fixes for the bundled Console Commands mod: * added new clothing items; * fixed spawning new flooring and rings (thanks to Mizzion!); diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs index 41ce7c37..36f2f650 100644 --- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs @@ -41,6 +41,10 @@ namespace StardewModdingAPI.Framework.ContentManagers /// <summary>A list of disposable assets.</summary> private readonly List<WeakReference<IDisposable>> Disposables = new List<WeakReference<IDisposable>>(); + /// <summary>The disposable assets tracked by the base content manager.</summary> + /// <remarks>This should be kept empty to avoid keeping disposable assets referenced forever, which prevents garbage collection when they're unused. Disposable assets are tracked by <see cref="Disposables"/> instead, which avoids a hard reference.</remarks> + private readonly List<IDisposable> BaseDisposableReferences; + /********* ** Accessors @@ -84,6 +88,7 @@ namespace StardewModdingAPI.Framework.ContentManagers // get asset data this.LanguageCodes = this.GetKeyLocales().ToDictionary(p => p.Value, p => p.Key, StringComparer.InvariantCultureIgnoreCase); + this.BaseDisposableReferences = reflection.GetField<List<IDisposable>>(this, "disposableAssets").GetValue(); } /// <summary>Load an asset that has been processed by the content pipeline.</summary> @@ -276,6 +281,9 @@ namespace StardewModdingAPI.Framework.ContentManagers assetName = this.AssertAndNormalizeAssetName(assetName); this.Cache[assetName] = value; } + + // avoid hard disposable references; see remarks on the field + this.BaseDisposableReferences.Clear(); } /// <summary>Parse a cache key into its component parts.</summary> |