【问题标题】:Advoid Memory Leak in Windows Phone 8避免 Windows Phone 8 中的内存泄漏
【发布时间】:2014-09-06 16:50:16
【问题描述】:

我在这里遇到问题:(
我正在尝试通过 XAML 编写一个小游戏,一种重复回合游戏。 我使用 Storyboard 来显示经过的转弯时间(通常为 3-6 秒),方法是在图像 (processbar.png) 和 Stackpanel (spImageList) 上移动指针,在每个转弯处我操作并删除了一些 BitmapImage。代码如下所示:

<Grid Grid.Column="1">
            <Canvas Canvas.ZIndex="1" >
                <Canvas.Resources>
                    <Storyboard x:Name="myStoryboard" Completed="myStoryboard_Completed">
                        <!-- Animate the center point of the ellipse. -->
                        <DoubleAnimation Storyboard.TargetName="Pointer"
                                     Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"
                                     Duration="0:0:7"                                          
                                     From="15" To="310"/>
                    </Storyboard>
                </Canvas.Resources>
                <Image Source="/Assets/Image/pointer.png" x:Name="Pointer">
                    <Image.RenderTransform>
                        <CompositeTransform TranslateX="15"/>
                    </Image.RenderTransform>
                </Image>
            </Canvas>
            <Image Source="/Assets/Image/processbar.png" Width="350"/>
        </Grid>

<Grid Grid.Row="2" HorizontalAlignment="Center" Margin="0,10,0,0">
        <StackPanel x:Name="spImageList" Orientation="Horizontal" HorizontalAlignment="Center" Canvas.ZIndex="1"  />
        <Image Source="/Assets/Image/background.png" Width="550"/>
    </Grid>

c#代码

private void myStoryboard_Completed(object sender, EventArgs e)
    {
        spImageList.Children.Clear();      // remove all image from last turn          
        myStoryboard.Begin();

        // Manipulated Images for new turn;   
        ...      
        //

        foreach (var img in ImageList)
            spImageList.Children.Add(img);
    }

游戏结束后,当人们离开页面时,我使用了这段代码:

protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        myStoryboard.Stop();
        spImageList.Children.Clear();          
        base.OnNavigatedFrom(e);
        Debug.WriteLine("mem navigate from Playpage: " + GC.GetTotalMemory(true).ToString());
    }  

但是在我玩了 2 或 3 场游戏之后,应用程序运行缓慢且卡顿,最终导致我的应用程序崩溃。 我使用了 Debug.writeline,发现内存应用程序即使在 MainPage 也没有减少(从 PlayPage 导航后)我清除了导航缓存并使用 GC 收集。

if (this.NavigationService.CanGoBack)
        {
            while (this.NavigationService.BackStack.Any())
            {
                this.NavigationService.RemoveBackEntry();
            }
        }
GC.Collect();

所以我只是想知道是否有正确的方法来避免这里的内存泄漏(我认为这是因为我在游戏中操纵的故事板和图像)

【问题讨论】:

    标签: c# windows-phone-8


    【解决方案1】:

    存在与图像类相关的泄漏。

    确保在丢失对图像的引用之前执行此操作:

    BitmapImage bitmapImage = image.Source as BitmapImage;
    bitmapImage.UriSource = null;
    image.Source = null;
    

    更多解释见herehere,还有:Why do I get an OutOfMemoryException when I have images in my ListBox?

    【讨论】:

    • 所以行:spImageList.Children.Clear();没有清除图像?这很奇怪 :) 故事板怎么样,它是暴露了自己还是我必须对它做点什么?
    • "这很奇怪" 是的,它是 :) 将 Image 视为 IDisposable,无法调用 Dispose - 您需要使用上面的代码 sn-p 来“处理”一个图像。这是框架中的一个已知缺陷/错误。这些图像可能会导致内存泄漏,但我不能保证这是唯一的泄漏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 1970-01-01
    • 2014-07-01
    • 1970-01-01
    • 2014-05-03
    相关资源
    最近更新 更多