如何在 MAUI Shell 应用程序中使用 Navigation.PushAsync() 后释放内存?

问题描述 投票:0回答:1

当我使用 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 能够修复它。没有这样的运气。

你有没有看到每页弹出后强制释放内存的方法?不同的导航策略是否更有可能释放内存?我真的想避免改变导航方法,因为它需要对实际应用程序进行大量重写,这给我带来了麻烦。

感谢您提供的任何帮助。

memory-leaks navigation maui
1个回答
0
投票

这是 GitHub 上的一个已知问题,它与 Collectionview 内存泄漏有关。您可以跟进问题并提供您遇到的问题信息。

以下是 GitHub 上的问题主题,您可以参考。

  1. Windows下ListView/CollectionView内存泄漏
  2. 滚动时 CollectionView 中出现大量内存泄漏
  3. [net7.0 / net8.0] [iOS] CollectionView.ItemsSource 更改时内存泄漏
© www.soinside.com 2019 - 2024. All rights reserved.