【问题标题】: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();
    }

【问题讨论】:

    标签: c# xaml memory-management win-universal-app windows-10


    【解决方案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 时会立即释放内存。

      【讨论】:

        猜你喜欢
        • 2015-10-25
        • 2012-08-13
        • 2016-12-24
        • 1970-01-01
        • 2017-05-14
        • 2017-11-02
        • 1970-01-01
        • 2013-08-10
        • 1970-01-01
        相关资源
        最近更新 更多