为什么我的WPF无法释放内存?

时间:2013-11-07 09:13:40

标签: c# wpf memory-management

也许我提供的信息太少,这是我的错。这是我的项目:

LoginWindow.xaml:

<Window x:Class="IEXM.LoginWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="LoginWindow" 
        Height="300" Width="300">
    <Grid Height="228">
        <Grid.ColumnDefinitions>
        <ColumnDefinition Width="214*" />
        <ColumnDefinition Width="64*" />
        </Grid.ColumnDefinitions>
        <Button Click="New_One" FontSize="50" Margin="0,0,0,113" Grid.ColumnSpan="2">New One</Button>
        <Button Click="Delete" FontSize="50" Margin="0,121,0,0" Grid.ColumnSpan="2">Delete</Button>
    </Grid>
</Window>

LoginWindow.xaml.cs:

using System;
using System.Linq;
using System.Windows;

namespace IEXM
{
    public partial class LoginWindow : Window
    {
        MainWindow w;
        public LoginWindow()
        {
            InitializeComponent();
        }

        private void Delete(object sender, RoutedEventArgs e)
        {
            if (w == null)
                return;
            w.Close();
            w = null; 
            GC.Collect();
        }

        private void New_One(object sender, RoutedEventArgs e)
        {
            w = new MainWindow();
            w.Show();
        }
    }
}

MainWindow.xaml:

<Window x:Class="IEXM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Width="380" Height ="265"
        xmlns:gifLib="clr-namespace:WpfAnimatedGif;assembly=WpfAnimatedGif" >
    <ScrollViewer Width="300" Height ="165" Name="sc">
        <ItemsControl  Name="wp_face">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel ItemHeight="40" ItemWidth="40"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <Image Name="img"  
                               Tag="{Binding source}" 
                               Style="{StaticResource CWFacePopupGifImageStyle}"/>
                    </WrapPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</Window>

MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace IEXM
(
    public partial class MainWindow : Window
    (
        public class ImageItem : INotifyPropertyChanged
        (
            protected string _source;

            public string source
            (
            get     ( return _source; }
            set
                (
                    _source = value;
                    OnPropertyChanged("source");
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string propertyName)
            (
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }

            public ImageItem(string _source)
            (
                this._source = _source;
            }
        }

        public MainWindow()
        (
            InitializeComponent();

            ObservableCollection<ImageItem> gifList = new ObservableCollection<ImageItem>();
            for (int i = 0; i < 107; ++i)
            (
                gifList.Add(new ImageItem(
                    "pack://application:,,,/Expression/f" + i.ToString().PadLeft(3, '0') + ".gif"));
            }
            wp_face.ItemsSource = gifList;
        }

        protected override void OnClosed(EventArgs e)
        (
            wp_face.ItemsSource = null;
            base.OnClosed(e);
        }
    }
}

和app.xaml:

<Application x:Class="IEXM.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="LoginWindow.xaml"
             xmlns:gifLib="clr-namespace:WpfAnimatedGif;assembly=WpfAnimatedGif">
    <Application.Resources>
        <Style x:Key="CWFacePopupGifImageStyle" TargetType="Image">
            <Setter Property="Width" Value="36" />
            <Setter Property="Height" Value="36" />
            <Setter Property="gifLib:ImageBehavior.AnimatedSource" 
                    Value="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" />
            <Setter Property="gifLib:ImageBehavior.RepeatBehavior" Value="0" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="gifLib:ImageBehavior.RepeatBehavior" Value="Forever" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Application.Resources>
</Application>

在点击“新的一个”之前,需要11,992KB的内存,点击“新的一个”之后是50,724KB,但是点击“删除”之后,提高到51,996KB,之后没有减少那。那我的代码出了什么问题?

PS:107 GIF总共1.9MB。

1 个答案:

答案 0 :(得分:2)

我将MainWindow替换为Window并运行代码。据我所见,它没有产生任何内存泄漏,所以泄漏就在你的代码中。如果没有更多信息,我们不能说是什么,但你可以尝试使用CLR Profiler来查找分配的对象。

可在此处找到CLR Profiler:http://clrprofiler.codeplex.com/

可以在这里找到一个很好的教程:http://msdn.microsoft.com/en-us/library/ff650691.aspx 在这里:http://www.codeproject.com/Articles/45292/NET-Best-Practice-No-1-Detecting-High-Memory-cons