如何强制通用应用程序释放内存?

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 时会立即释放内存。

【讨论】:

以上是关于如何强制通用应用程序释放内存?的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 SQL Server 释放内存?

如何强制 Django 模型从内存中释放

有没有办法强制 JavaFX 释放视频内存?

怎么用new定义一个类数组,并且释放内存

如何在Python中显式释放内存?

linux下清理内存以及swap