如果TabItem被删除,如何释放内存?

时间:2016-03-24 14:12:12

标签: c# wpf xaml memory tabcontrol

enter image description here

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

  • 窗口出现==>内存使用量为19.3 MB
  • 选择"标签B" ==>内存使用率上升到40.3 MB
  • 点击按钮"行动"删除" Tab 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 个答案:

答案 0 :(得分:1)

.NET(通常,大多数垃圾收集环境)在不再使用对象时不会确定性地释放内存。它将这些项目标记为有资格收集,并在它认为合适时释放它们(垃圾收集器中的算法考虑了许多因素:系统上的内存压力,是否正在执行可能受其影响的其他进程收集时减速等。)

你可以通过调用GC.Collect()来“半” - 强制执行垃圾收集,但普遍的共识是,除非有充分的理由,否则你应该这样做。决定是否需要记忆的算法以及集合必须具有多大的积极性的算法是由通常比你更了解的聪明人做出的: - )

如果你有内存问题(有内存问题意味着你的系统内存不足,而不是你的进程使用的内存超过了你应该考虑的内存),那么是时候找到“泄漏”,否则不需要的对象引用阻止垃圾收集器完成它的工作......但如果你没有这些问题,那么任务管理器中进程占用的内存不足以让它认为它不能正常工作。< / p>

此外,.NET CLR在本机堆上保留内存以使托管分配和释放更快(这基本上是任务管理器向您显示的内容,CLR为您的进程分配了多少内存),这就是称为“托管堆”。所以,即使垃圾收集器实际上释放了你的控制权,一般而且除非有理由不这样做,否则它会为你的进程保留一些内存,这样如果你需要创建其他的托管对象,它就会放保留内存中的那些对象:再次,除非有没有保留内存的原因(例如:系统内存不足,例如),你在任务管理器上看到它分配的事实是无关紧要的,不是意味着它没有做好自己的工作。

尊重更多基础文献: