我在这里使用了登录示例:https://github.com/davidortinau/ShellLoginSample
shell看起来像:
<ShellItem Route="login">
<ShellContent ContentTemplate="{DataTemplate local:LoginPage}"/>
</ShellItem>
<TabBar Route="main">
<Tab Title="Browse" Icon="tab_feed.png">
<ShellContent
ContentTemplate="{DataTemplate local:ItemsPage}" />
</Tab>
<Tab Title="About" Icon="tab_about.png">
<ShellContent
ContentTemplate="{DataTemplate local:AboutPage}" />
</Tab>
<Tab Title="Admin" IsVisible="{Binding IsAdmin}">
<ShellContent
ContentTemplate="{DataTemplate local:AdminPage}"/>
</Tab>
</TabBar>
其中,最初在应用程序开始时,用户被导航到LoginPage,然后从登录页面导航到MainPage(ItemsPage)。
await Shell.Current.GoToAsync("//main");
我在ItemsPage中添加了额外的逻辑,在这里我强制执行GC。
private void Button_Clicked(object sender, EventArgs e){
Device.BeginInvokeOnMainThread(async () =>{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
await Task.Delay(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
});
}
但是从xamarin profiler中我可以看到LoginPage仍然在内存中。它应该被GC收集吗?
1条答案
按热度按时间whhtz7ly1#
首先,我不能确定你是否强制GC成功,你可以参考[BUG] Xamarin Shell Navigation Memory leak的问题中关于GC的代码。
此外,我检查了您提供的示例中的代码,发现它使用了LoginPage中的MessageCenter。即使MessagingCenter类使用弱引用并允许它们被垃圾收集。
但是就像这篇关于消息中心的评论说的,一次调用
await Shell.Current.GoToAsync("//main");
不会得到gc,而且LoginPage是消息中心的发布者,我不能确定它是否应该被回收,你可以参考关于Pages created by Shell.Current.GoToAsync are not re-used or disposed的问题。但是你可以尝试删除关于messagecenter的代码,他们在链接中使用了关于强制GC的代码,然后再次测试。