2010-01-29 49 views
7

我遇到了当鼠标移动到我的WPF应用程序上时非托管内存泄漏的情况。特别是,当我在perfmon或Red Gate的内存分析器中剖析应用程序时,私有字节单调增加,但所有托管堆中的字节保持不变 - 我相信这意味着应用程序具有非托管泄漏。在一个微不足道的WPF应用程序中的非托管泄漏

我创建了一个简单的repro应用程序,但我看不到问题出在哪里。

该应用程序由一个带有四个项目的ListView组成。将鼠标快速移动到这些项目上会导致问题。

这里是代码,如果你有兴趣重现这个问题 - 这不是很好,但很简单。

感谢


编辑:我创建了这个问题的Microsoft Connect issue


的App.xaml

<Application x:Class="WpfLeakRepro.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    StartupUri="Window1.xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="Generic.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

App.xaml.cs

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Data; 
using System.Linq; 
using System.Windows; 

namespace WpfLeakRepro 
{ 
    /// <summary> 
    /// Interaction logic for App.xaml 
    /// </summary> 
    public partial class App : Application 
    { 
    } 
} 

Generic.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <LinearGradientBrush x:Key="ListItemHover" 
         EndPoint="0,1" 
         StartPoint="0,0"> 
     <GradientStop Color="Aqua" 
         Offset="0" /> 
     <GradientStop Color="White" 
         Offset="1" /> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="ListItemSelected" 
         EndPoint="0,1" 
         StartPoint="0,0"> 
     <GradientStop Color="Blue" 
         Offset="0" /> 
     <GradientStop Color="White" 
         Offset="1" /> 
    </LinearGradientBrush> 
    <VisualBrush x:Key="CheckeredBackground" 
       Viewport="20,20,20,20" 
       ViewportUnits="Absolute" 
       TileMode="Tile" 
       Stretch="Fill"> 
     <VisualBrush.Visual> 
      <Canvas Opacity="5"> 
       <Rectangle Fill="#FF606060" 
          Height="21" 
          Width="21" 
          Canvas.Top="20" /> 
       <Rectangle Fill="#FF606060" 
          Width="21" 
          Height="21" 
          Canvas.Left="20" /> 
       <Rectangle Fill="#FF646464" 
          Height="21" 
          Width="21" 
          Canvas.Left="20" 
          Canvas.Top="20" /> 
       <Rectangle Fill="#FF646464" 
          Width="21" 
          Height="21" /> 
      </Canvas> 
     </VisualBrush.Visual> 
    </VisualBrush> 
    <Style TargetType="{x:Type ListViewItem}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ListViewItem}"> 
        <Border Background="{TemplateBinding Background}"> 
         <Grid> 
          <GridViewRowPresenter /> 
         </Grid> 
        </Border> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsMouseOver" 
           Value="true"> 
          <Setter Property="Background" 
            Value="{DynamicResource ListItemHover}" /> 
         </Trigger> 
         <Trigger Property="IsSelected" 
           Value="true"> 
          <Setter Property="Background" 
            Value="{DynamicResource ListItemSelected}" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 

       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

Window1.xaml

<Window x:Class="WpfLeakRepro.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="449" Width="497"> 
    <Grid> 
     <ListView Margin="12" 
        Name="listView" 
        ItemsSource="{Binding}"> 
      <ListView.View> 
       <GridView> 
        <GridView.Columns> 
         <GridViewColumn Header="File Name"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Name}" /> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
         <GridViewColumn Header="Thumbnail"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <Border Background="{DynamicResource CheckeredBackground}" Width="72" Height=48/> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
        </GridView.Columns> 
       </GridView> 
      </ListView.View> 
     </ListView> 
    </Grid> 
</Window> 

Window1.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; 
using System.IO; 

namespace WpfLeakRepro 
{ 
    public class Picture 
    { 
     public string Name { get; set; } 
    } 

    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      List<Picture> pictures = new List<Picture>(); 

      string[] images = new string[] {"Blue hills.jpg", "Sunset.jpg", "Water lilies.jpg", "Winter.jpg" }; 

      foreach (string imagePath in images) 
      { 
       pictures.Add(new Picture() { Name = imagePath }); 
      } 

      DataContext = pictures; 
     } 
    } 
} 

回答

1

该问题似乎与用于格子背景的VisualBrush有关。将其替换为SolidColorBrush,问题就消失了。但是这并不重要:微软的人们建议我安装最新的.NetFx 3.5sp1升级版本,这似乎解决了这个问题(更多详情here)。

6

你可能已经创建了WPF绑定一个已知的内存泄漏未结合的类的属性时可能出现的实施INotifyPropertyChanged。在你的情况下Picture类的Name财产。

解决方案正在将绑定模式设置为一次性,让Picture实现INotifyPropertyChanged或使Name成为依赖项属性。

了解更多关于ms supportthis blog post。这些和其他已知的WPF内存泄漏可以在here找到。

+0

我不认为这是问题所在。 'Picture'用于实现'INotifyPropertyChanged',但我删除它来缩短我的repro应用程序。此外,如果这是问题,我相信泄漏将被管理 - 数据绑定系统将保持引用它不应该引用的管理对象。 WPF泄漏列表是一个很好的选择(我建议每个人都检查一下),但是我已经查看了这个列表,我认为只有#2适用,这就是你提到的问题,这似乎不是问题这里。我真的认为这个问题是一个新问题。 – 2010-02-07 00:22:53

相关问题