Почему моя работа WPF не освобождает память?
Может быть, я дал слишком мало информации, это моя вина. Вот мой проект:
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>
До того, как я нажал "New One", потребовалось 11 992 КБ памяти, а после нажатия "New One" - 50 724 КБ, но после нажатия "Удалить" он поднялся до 51 996 КБ и не уменьшился после этого. Так что не так с моим кодом?
PS: 107 картинок полностью 1,9 МБ.
1 ответ
Я заменил 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