如何强制通用应用程序释放内存?
Posted
技术标签:
【中文标题】如何强制通用应用程序释放内存?【英文标题】:How to force Universal Application to release memory? 【发布时间】:2015-11-06 16:13:53 【问题描述】:创建了一个泄漏内存的简单应用:
查看
<Page
...
x:Class="App3.MainPage"
mc:Ignorable="d">
<StackPanel>
<Image Width="300" Height="200"
Source="/Assets/BBlHOiv.jpg"></Image>
<Button Click="Button_Click">Navigate</Button>
</StackPanel>
</Page>
代码背后
public sealed partial class MainPage : Page
public MainPage()
this.InitializeComponent();
private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
this.Frame.Navigate(typeof(MainPage));
每次单击按钮时,代码都会导航到相同的页面,该页面上有大约 400KB 的图像。如果我继续快速单击按钮,则每次单击或几次单击都会增加内存。内存没有被回收,或者至少没有被及时回收。在真正的应用程序中,页面更复杂,导航更复杂(包括循环导航),这可能会成为一个大问题。问题是,如何强制应用释放内存?理想情况下,一旦不再需要/显示页面。
我尝试了以下方法,但没有成功。
#1 清除框架的导航堆栈
protected override void OnNavigatedFrom(NavigationEventArgs e)
base.OnNavigatedFrom(e);
this.Frame.BackStack.Clear();
#2 使用 MVVM 时,将 DataContext 设置为 null(当在 XAML 标记中设置 datacontext 时)
protected override void OnNavigatedFrom(NavigationEventArgs e)
base.OnNavigatedFrom(e);
this.DataContext = null;
this.Frame.BackStack.Clear();
【问题讨论】:
【参考方案1】:.Net 中的垃圾收集器按照自己的节奏进行,不一定在关闭时进行。我不建议这样做,但您可以手动调用GC.Collect();
。我会追查“泄漏”的来源。
有关垃圾收集过程的更多信息: https://msdn.microsoft.com/en-us/library/xe0c2357%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
【讨论】:
【参考方案2】:如果图片的数量和大小不是太大,图片可以作为静态资源加载到 App 对象中,页面可以引用这些(StaticResource)。这样它们只会在启动时加载一次,并且应该很快就会出现。
如果这需要太多内存,另一种方法是在打开页面时在代码中加载图像,保留对图像的引用,并在页面关闭时显式处理图像。这会更慢,但可能会节省内存。同样,如前所述,不能保证调用 Dispose 时会立即释放内存。
【讨论】:
以上是关于如何强制通用应用程序释放内存?的主要内容,如果未能解决你的问题,请参考以下文章