2016-03-24 73 views
0

enter image description here如何删除TabItem被删除时的内存?

谁运行下面的应用程序会注意到:

  • 窗口已经出现==>内存使用率19.3 MB
  • 选择 “选项卡B” ==>内存使用率上升至40.3 MB
  • 点击按钮 “操作” 删除 “选项卡B” ==>内存使用 下降到39.4 MB

问题:如何将内存消耗缩减至19.3 MB?

应用代码Xaml

<Window x:Class="WpfApplication2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApplication2" 
     mc:Ignorable="d" 
     Title="MainWindow" 
     FontSize="14" 
     WindowStartupLocation="CenterScreen" 
     Height="230" 
     Width="530" 
     Visibility="Visible" 
     Loaded="Window_Loaded"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 
     <TabControl Name="tabControl" Grid.Row="0"> 
      <TabItem Name="tabItem_1" Header="--- Tab A ---" /> 
      <TabItem Name="tabItem_2" Header="--- Tab B ---"> 
       <RichTextBox Name="rtb" 
          IsDocumentEnabled="True" 
          VerticalContentAlignment="Top" 
          HorizontalContentAlignment="Left" 
          ScrollViewer.CanContentScroll="True" 
          ScrollViewer.VerticalScrollBarVisibility="Auto" 
          IsReadOnly="False" 
          AcceptsTab="True" 
          Margin="5,5,5,5" 
          Padding="5,5,5,5"/> 
      </TabItem> 
     </TabControl> 
     <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,10,10"> 
      <Button Name="buttonAction" Content=" _Action " Click="buttonAction_Click" /> 
      <Button Name="buttonCancel" Content=" _Cancel " Click="buttonCancel_Click" IsCancel="True" Margin="10,0,0,0" /> 
     </StackPanel> 
    </Grid> 
</Window> 

应用代码C#

using System.Windows; 
using System.Windows.Documents; 
using System.Windows.Media; 

namespace WpfApplication2 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     /// <summary> 
     /// OnLoad. 
     /// </summary> 
     private void Window_Loaded(object sender, RoutedEventArgs e) 
     { 
      for (int i = 0; i < 6000; i++) 
      { 
       Run run = new Run("»Today is the day before tomorrow.« – »Are you sure, Mr President?« "); 
       Bold bold = new Bold(run); 
       Paragraph para = new Paragraph(bold); 

       if (i % 2 == 0) 
        para.Background = Brushes.SandyBrown; 
       else 
        para.Background = Brushes.Khaki; 

       rtb.Document.Blocks.Add(para); 
      } 

      rtb.Document.Blocks.Remove(rtb.Document.Blocks.FirstBlock); 
      tabItem_1.Focus(); 
     } 

     /// <summary> 
     /// Button "Action". 
     /// </summary> 
     private void buttonAction_Click(object sender, RoutedEventArgs e) 
     { 
      tabControl.Items.RemoveAt(1); 
     } 

     /// <summary> 
     /// Button "Cancel". 
     /// </summary> 
     private void buttonCancel_Click(object sender, RoutedEventArgs e) 
     { 
      this.Close(); 
     } 
    } 
} 

回答

1

.NET(在一般情况下,最垃圾收集环境)不确定性地释放内存当不使用的对象了。它将这些项目标记为符合收集条件,并在适合时释放它们(垃圾收集器中有许多算法考虑了很多因素:系统的内存压力,是否正在执行其他可能受到收集资料时,等)放缓

你可以在“半成品” - 强制垃圾收集致电GC.Collect(),但普遍的共识是,你应该做,除非有充分的理由。确定内存是否需要的算法以及收集的必要程度是由非常聪明的人制定的,这些人通常比你知道得更好:-)

如果你有内存问题(有内存问题意味着你内存不足在系统上,不是你的进程使用的内存比你想象的要多),那么是时候发现“泄漏”了,否则就是不需要的对象引用,它们会阻止垃圾回收器完成它的工作......但如果你没有这些问题,任务管理器中的进程占用的内存不足以让它认为它不能正常工作。另外,.NET CLR在本地堆上保留内存以更快地进行托管分配和释放(这基本上是任务管理器向您显示的内容,CLR为您的进程分配了多少内存),这就是被称为“托管堆”。所以,即使垃圾收集器实际上释放了你的控制权,一般情况下,除非有一个不合理的原因,否则它会保留一些为你的进程保留的内存,所以如果你需要创建其他管理对象,它会把这些保留内存中的对象:再次,除非有理由不保留该内存(例如:系统内存不足),否则您看到它在任务管理器上分配的事实是不相关的,不会意味着它没有完成它的工作。

更多基本文献到方面: