Window Form 控件 vs WPF 控件 内存比较






4.96/5 (25投票s)
WinForm 控件和 WPF 控件的内存管理以及它们如何加载的内部机制
引言
这是对 Windows Form 控件和 WPF 控件的分析,以及它们如何消耗系统的内存。它深入研究了正在创建的对象以及两种应用程序类型所消耗的内存占用。
背景
Windows Forms 已经存在很长时间了,用于在 Windows 平台上开发应用程序。2007 年,WPF 作为 Windows Form 应用程序的替代品推出,并进行了新的增强。这是基于内存利用率的 Windows Form 应用程序与 WPF 应用程序的比较。
Using the Code
为了比较这两种应用程序类型,我们需要使用类似的控件来创建应用程序。
对于此示例,我选择了 TextBox
控件。选择 TextBox
控件的原因是,在 Windows Form 应用程序中,TextBox
类继承自 (System.Windows.Forms.dll) 中的 System.Windows.Forms.Control
。
WPF 应用程序的 TextBox
类直接继承自 System.Windows.Controls.Primitives.Control
(PresentationFramework.dll)。
因此,WPF 中的 TextBox
控件不从 ContentControl
继承,从而避免了额外的对象创建开销。
可以认为,我们可以使用 Windows form 的 Label
和 TextBlock
,但是让我们使用 TextBox
,因为几乎所有实际应用程序都会在某个地方使用它。
首先,我们将在 Windows Form 和 WPF 应用程序上创建 1000 个 TextBox
对象,并在屏幕上呈现它们。我们将衡量内存利用率,并检查创建了多少个对象以及使用了多少内存来完成相同的操作。
让我们创建一个简单的 Windows Form 应用程序,并将以下代码添加到其中
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsPerformance
{
public partial class WindowsForm : Form
{
private System.Windows.Forms.TextBox textbox1;
int Iteration = 1000;
public WindowsForm()
{
InitializeComponent();
CreateMultipleTextControls();
}
public void CreateMultipleTextControls()
{
for (int i = 0; i < Iteration; i++)
{
this.textbox1 = new System.Windows.Forms.TextBox();
this.textbox1.Location = new System.Drawing.Point(10, 10);
this.textbox1.Name = "textbox" + i;
this.textbox1.Size = new System.Drawing.Size(150, 150);
this.textbox1.BackColor = Color.Blue;
this.textbox1.TabIndex = 0;
this.textbox1.Text = "textbox";
this.Controls.Add(textbox1);
}
}
}
}
让我们创建一个简单的 WPF 应用程序,并将以下代码添加到其中
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WPFWinPerformance
{
public partial class MainWindow : Window
{
int Iteration = 1000;
private TextBox textbox1;
public MainWindow()
{
InitializeComponent();
CreateMultipleTextControls();
}
public void CreateMultipleTextControls()
{
for (int i = 0; i < Iteration; i++)
{
this.textbox1 = new TextBox();
this.textbox1.Name = "textbox" + i;
this.textbox1.TabIndex = 0;
this.textbox1.Text = "Text";
this.textbox1.Width = 150;
this.textbox1.Height = 150;
this.textbox1.Background = new SolidColorBrush(Colors.DarkBlue);
this.textbox1.Margin = new Thickness(10, 10, 10, 10);
this.Grid1.Children.Add(textbox1);
}
}
}
}
当您使用 Visual Studio 2015 中使用的诊断工具 运行应用程序时,结果如下。
对于内存使用情况,我们采取了两个快照来检查内存使用情况。
第一个快照之后
InitializeComponent();
第二个快照之后
CreateMultipleTextControls();
1) Windows 应用程序
Windows 摘要:在这里,在第一个快照中,创建了 1247 个对象,应用程序占用 94.35 KB 大小。
在第二个快照中,当创建了 1000 个文本框时,呈现的应用程序创建了 14327 个对象,应用程序大小为 654.77 KB。
2) WPF 应用程序
WPF 摘要:在这里,在第一个快照中,创建了 12702 个对象,应用程序占用 595.80 KB 大小。
在第二个快照中,当创建了 1000 个文本框时,呈现的应用程序创建了 4,04,324 个对象,应用程序大小为 17,689.31 KB。
因此,与 Windows 应用程序相比,WPF 应用程序肯定会占用大量内存。但是可以理解的是,在控件的外观和感觉方面,WPF 比 Windows 提供了更多的灵活性,而且 WPF 也会根据视觉树来呈现控件,这也是一个开销。撇开所有这些额外的部分,让我们检查一下应用程序中还有哪些其他属性正在利用内存。深入研究创建的对象,您可以检查每个对象正在消耗的内存。
下图显示了在快照 1 和快照 2 中加载的 Windows Forms 应用程序对象。它表明,Windows Forms 在快照 1 中几乎没有创建任何大型对象,最大的对象是图标,而在呈现 1000 个文本框后,Textbox
和 PropertyStore
占用了最大内存,这是预期的,因为为 Windows Form 中的每个控件创建了 Property Store 实例。
下图显示了在快照 1 和快照 2 中加载的 WPF 应用程序对象。它表明 WPF 应用程序创建了一些对象,例如应用程序中所有依赖属性的单个实例和其他应用程序所需的常见对象。但是快照 2 更大,因为 Textbox
类在内部需要创建 ScrollViewer
、Rectangle
、Border
、Vertical
/Horizontal
Scrollbar,这会增加应用程序的大小。它也有依赖属性被创建,但由于相同类型的依赖属性的单个实例,它们的占用空间较小,这与 Windows 形式不同,在 Windows 形式中,当控件数量增加时,PropertyStore
会增加。
结论
详细信息的摘要
上述摘要表明,WPF 控件的内存占用比其对应的 Windows 控件要高得多,因为 WPF 控件的设计方式不同,并且需要初始化更多更小的单元来创建一个控件。但需要观察的一件事是,WPF 总加载时间优于 Win form 应用程序。我将在下一篇文章中介绍为什么会发生这种情况。
Coding is Simple
历史
- 2015 年 10 月 10 日:初始版本