diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index 12abc4d867..5d015ca5ab 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -461,12 +461,43 @@ namespace osu.Game.Skinning
var sample = Samples?.Get(lookup);
if (sample != null)
- return sample;
+ return new LegacySkinSample(sample, this);
}
return null;
}
+ ///
+ /// A sample wrapper which keeps a reference to the contained skin to avoid finalizer garbage collection of the managing SampleStore.
+ ///
+ private class LegacySkinSample : ISample
+ {
+ private readonly Sample sample;
+
+ [UsedImplicitly]
+ private readonly LegacySkin skin;
+
+ public LegacySkinSample(Sample sample, LegacySkin skin)
+ {
+ this.sample = sample;
+ this.skin = skin;
+ }
+
+ public SampleChannel Play()
+ {
+ return sample.Play();
+ }
+
+ public SampleChannel GetChannel()
+ {
+ return sample.GetChannel();
+ }
+
+ public double Length => sample.Length;
+
+ public Bindable PlaybackConcurrency => sample.PlaybackConcurrency;
+ }
+
private IEnumerable getLegacyLookupNames(HitSampleInfo hitSample)
{
var lookupNames = hitSample.LookupNames.SelectMany(getFallbackNames);