使用 Windows 窗体和图形节省内存
· 对提供
BeginUpdate 和
EndUpdate 方法的控件使用这两种方法,提供这两种方法的控件包括
ComboBox、ListBox、ListView、ToolStripComboBox
和
TreeView。
· 重新定位控件时,使用
SuspendLayout
和
ResumeLayout
方法。
· 在后台加载其他窗体,使用数据来填充控件,然后再使用
Show
方法。
· 将事件处理代码限制为仅执行重要任务,以便挂起过程可以继续。
· 使用脱屏位图。有关示例,请参见如何:绘制后台图像。
· 重写控件上的
OnKeyDown、OnKeyPress
和
OnKeyUp
方法,而不是添加按键事件处理程序。
使用数据和字符串节省内存
· 在
for 循环中使用整数变量(Int32
或
Int64),而不使用对象变量。
· 避免使用枚举的
ToString
方法,因为它会搜索元数据表,从而影响性能。
· 避免
OutOfMemoryException
错误。如果没有足够的内存分配给内部使用或分配给新对象实例,公共语言运行库可能会引发此异常。要避免此异常,应避免编写占用
64K 或更多内存的大方法。
· 移除
System.SR.dll,它包含异常对话框的错误信息字符串。部署应用程序时可以不使用此文件,从而节省内存。如果存在
System.SR.dll,则
.NET Compact Framework 将动态加载
System.SR.dll 中包含的错误字符串。
· 字符串是不可变的,因此,每次修改该字符串时都会创建新的
String
对象。构造需经常修改的字符串时,请考虑使用
StringBuilder。
· 如果您知道用于
DateTime
序列化的确切格式,请为
DateTime 使用
ParseExact
方法。否则,DateTime分析器将按顺序尝试应用多个特定于区域性的格式。
· 限制打开 SqlCeCommand 对象的数量,并在完成后释放它们。
与本机代码进行交互时节省内存
· 在平台调用操作中,使用可直接复制到本机结构中的类型,这样的类型在托管和非托管内存中有一种通用表示形式,如
Int32 或
IntPtr。对于大于
32 位的可直接复制到本机结构中的值类型来说,通过引用传递比通过值传递更快。有关可直接复制到本机结构中的类型的更多信息,请参见
.NET
Compact Framework 中可直接复制到本机结构中的类型。
· 为函数签名中的参数使用
InAttribute
和
OutAttribute
属性可以减少不必要的封送处理。
· 使用
Marshal
类中的方法手动在
IntPtr 和托管对象之间转换,如
PtrToStructure、PtrToStringBSTR、GetObjectForNativeVariant
和
GetObjectForIUnknown。
· 使用
Prelink
和
PrelinkAll
方法来引发支持本机到托管调用的存根
(stub) 的
JIT 编译。
· 如果期望您的本机
COM 对象通常情况下返回
S_FALSE,或其他非
S_OK HRESULT 值,则应将
PreserveSig
字段设置为
true,并使托管签名与本机签名匹配。这就避免了运行库将
HRESULT 值转换为
COM 调用上的异常时必需的
try/catch 块的系统开销。
· 尽量使用一个平台调用多做工作,尽量少用多个调用。
在集合中节省内存
· 如果集合基于数组,请使用索引器。
· 一旦有机会,就指定集合的大小,因为动态调整大小可以大大增加额外的存储。
· 使用泛型集合以避免值类型的装箱和取消装箱产生的系统开销。定义您自己的优化集合可实现最佳性能。
在 XML 中节省内存
· 使用
XmlTextReader
和
XmlTextWriter
代替
XmlDocument(因为它占用的内存较多)。
· 指定
XmlReaderSettings
和
XmlWriterSettings
的设置以改善性能。如果
IgnoreWhitespace
和
IgnoreComments
两个属性值适用,它们可以显著改善性能。
· 使用
UTF-8、ASCII
和
UTF-16 字符编码,它们比
ANSI 和
Windows 代码页编码更快。
· 避免使用用于分析的架构,因为这种架构需要更多的验证工作。
· 当从
XML 源填充
DataSet
窗体时,应将列映射为属性并使用类型化
DataSet。
· 填充
DataSet 时,应避免填充以下各项:
o 架构推理。
o 嵌套表。
o 多个
DateTime 列。为了获得更好的性能,请使用
Ticks
属性值。
· 使用
XML 反序列化时,遵循以下准则可改善性能:
o 使元素和属性名尽量保持简短,因为每个字符都必须经过验证。
o 基于属性数据的
XML 比基于元素数据的
XML 要快。
o 如果适用,使用
System.Xml.XmlNodeReader.Skip
方法。
o 如果性能很重要,应考虑二进制序列化。
· 为
XML 序列化的每一种类型分别使用一个
XmlSerializer
实例,以减少用于搜索元数据的时间。
· 由于序列化大量 XML 可能会耗尽内存,应考虑通过使用 BinaryReader 和 BinaryWriter 生成自定义二进制序列化机制。
使用 Web 服务时节省内存
· 读取和编写
DataSet 时,应使用
DiffGram。有关更多信息,请参见
DiffGram。
· 以
XML 格式将远程
DataSet 及其架构保存到设备。
· 初始屏幕期间创建一个简单的
Web 服务方法调用,因为第一个调用比后面的调用要慢。
· 小心处理网络和数据错误。
· 某些情况下,可以手动将
DataSet 序列化为
XML 字符串,然后执行一个
Web 服务调用,这样可以提高性能。
在高级编程中节省内存
· 异步处理大操作。
· 避免虚拟调用。.NET
Compact Framework 运行库虚拟调用比静态调用或实例调用大约慢
30%。由于资源受约束,.NET
Compact Framework 不使用
vtable,因此必须通过转换类和接口层次结构来调用方法,但这是一种代价很高的操作。.NET
Compact Framework 维护已解析的虚拟调用的缓存,因此在大多数情况下,无须重新解释调用。
· 尽可能使用字段而不使用属性。
·
定义值类型时,重写
GetHashCode
和
Equals
方法。如果未重写它们,则运行库会在基
ValueType
类中使用这些方法的普通版本。
· 谨慎使用映射。出于调研目的将映射与非实例化类一起使用会影响应用程序中的实例化对象的性能。
· 确保
RESX 文件中的托管资源具有完全限定名,并且这些资源准确无误。它们必须具有正确的版本和
PublicKeyToken 字段。为未正确指定的类型查找最合适的替代类型会影响性能。
· 请注意,在某些情况下,直接从文件读取应用程序数据就足够了,这比使用 ResourceManager 效率更高。ResourceManager 可以在定位您的二进制资源之前在文件系统中探测多个位置来查找最匹配的附属程序集。为作业使用适当的工具。