当我使用 Navigation.PushAsync() 推送 ContentPage 后从导航堆栈中弹出 ContentPage 时,Shell 应用程序中出现内存未释放的问题。每次我创建一个新页面,将其推送到导航堆栈上,使用后退箭头弹出它并创建/推送 ContentPage 的新实例,从导航堆栈弹出的先前 ContentPage 会保留在内存中。我在 iOS 和 Mac Catalyst 上观察到这种行为。观察 Activity Monitor 中的进程,即使我在每次推送后使用 GC.Collect(),内存使用量也会不断增加并且永远不会减少。没有任何事件订阅可以防止对象被销毁。
我能够使用以下简化代码重现该问题,该代码使用 CollectionView 显示一长串对象。
具有一些属性的简单类:
public class PrimaryData
{
public string Title { get; set; }
public string SubTitle { get; set; }
public string IconFileName { get; set; }
public PrimaryData()
{
}
}
PrimaryData 对象列表:
public class PrimaryDataCollection
{
public List<PrimaryData> Collection { get; private set; }
public PrimaryDataCollection()
{
Collection = new();
for(var i=0; i<1000; i++ ) {
Collection.Add(
new PrimaryData { IconFileName = "iron_white.png", SubTitle = $"Sub{i}", Title = $"Title{i}" });
}
}
}
和一个简单的 ContentPage 来显示列表。这位于文件 DisplayPrimaryCollection.xaml 中:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MemoryLeak"
x:Class="MemoryLeak.DisplayPrimaryCollection"
Title="Display List">
<ContentPage.BindingContext>
<local:PrimaryDataCollection/>
</ContentPage.BindingContext>
<CollectionView ItemsSource="{Binding Collection}">
<CollectionView.ItemTemplate>
<DataTemplate>
<VerticalStackLayout>
<Label Text="{Binding Title}" />
<Label Text="{Binding SubTitle}" />
<Image Source="iron_white.png" HorizontalOptions="Start" WidthRequest="20" HeightRequest="30" />
<BoxView HeightRequest="1" VerticalOptions="End" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
这是每次按下主页上的按钮时执行的代码:
private async void OnPage1Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new DisplayPrimaryCollection());
GC.Collect();
}
每次按下主页上的按钮时,都会显示此...
我遍历了导航堆栈以验证之前的页面确实已从堆栈中弹出。我认为这可能是 MAUI 中的一个错误,并希望具有最新 MAUI 工作负载的 .NET 8 能够修复它。没有这样的运气。
你有没有看到每页弹出后强制释放内存的方法?不同的导航策略是否更有可能释放内存?我真的想避免改变导航方法,因为它需要对实际应用程序进行大量重写,这给我带来了麻烦。
感谢您提供的任何帮助。
这是 GitHub 上的一个已知问题,它与 Collectionview 内存泄漏有关。您可以跟进问题并提供您遇到的问题信息。
以下是 GitHub 上的问题主题,您可以参考。