【问题标题】:How to free memory if a TabItem is removed?如果 TabItem 被删除,如何释放内存?
【发布时间】:2016-03-24 14:12:11
【问题描述】:

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

  • 已出现窗口 ==> 内存使用量为 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();
        }
    }
}

【问题讨论】:

    标签: c# wpf xaml memory tabcontrol


    【解决方案1】:

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

    您可以通过调用GC.Collect()“半”强制垃圾回收,但普遍的共识是您应该这样做,除非有充分的理由这样做。确定是否需要内存以及收集必须具有多大攻击性的算法是由通常比您更了解的非常聪明的人制定的:-)

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

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

    更多基础文献:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-27
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-01
      • 1970-01-01
      相关资源
      最近更新 更多