规则 ID |
DA0018 |
类别 |
分析工具使用 |
分析方法 |
采样 |
消息 |
托管内存分配接近 32 位进程的默认限制。 您的应用程序可能受内存限制。 |
规则类型 |
警告 |
在使用采样、.NET 内存或资源争用方法进行分析时,必须收集至少 10 个样本才能触发此规则。
原因
分析运行期间收集的系统数据指示 .NET Framework 内存堆已接近托管堆在 32 位进程中可以达到的最大大小。 此最大大小是默认值。 它基于可为专用字节分配的进程地址空间的总量。 报告的值是已分析进程处于活动状态时堆的最大观测值。 请考虑使用 .NET 内存分析方法重新进行分析,并优化应用程序对托管资源的使用。
当托管堆的大小接近默认限制时,可能必须更频繁地调用自动垃圾回收进程。 这会增加内存管理的开销。
将只对 32 位计算机上运行的 32 位应用程序激发该规则。
规则说明
Microsoft .NET 公共语言运行时 (CLR) 提供了自动内存管理机制,该系统使用垃圾回收器从应用程序不再使用的对象回收内存。 垃圾回收器是面向代的,并假定许多分配的生存期都较短。 例如,本地变量的生存期应比较短。 新创建的对象从第 0 代 (gen 0) 开始,然后如果这些对象在运行垃圾回收后仍然存在,则它们进入第 1 代,最后如果应用程序仍然使用这些对象,则它们最终进入第 2 代。
超过 85 KB 的托管对象将在大型对象堆上进行分配,从而可以不用像较小对象那样频繁地进行垃圾回收和压缩。 大型对象是单独进行管理的,这是因为假定情况下大型对象更持久,并且将持久的大型对象与经常分配的较小对象混合在一起可能会产生最差情况的堆碎片。
当托管堆的总大小接近默认限制时,内存管理的开销通常会增加到某一点,从该点起会开始影响应用程序的响应性和可伸缩性。
如何调查警告
双击“错误列表”窗口中的该消息以导航到标记视图。 找到**“.NET CLR Memory\# Bytes in all Heaps”和“# Total committed bytes”列。 确定程序执行过程中是否有一些特定阶段的托管内存分配多于其他阶段。 将“# Bytes in all Heaps”列的值与“.NET CLR Memory\# of Gen 0 Collections”列、“.NET CLR Memory\# of Gen 1 Collections”列和“.NET CLR Memory\# of Gen 2 Collections”**列中报告的垃圾回收率进行比较,以确定托管内存分配的模式是否影响垃圾回收率。
在 .NET Framework 应用程序中,公共语言运行时将托管堆的总大小限制为略小于进程地址空间专用区域部分最大大小的一半。 对于 32 位计算机上运行的 32 位进程,2 GB 代表进程地址空间专用部分的上限。 当托管堆的总大小开始接近其默认限制时,管理内存的开销可能会增加,应用程序性能可能会下降。
如果托管内存开销过大是一个问题,请考虑以下选项之一:
优化应用程序对托管内存资源的使用
- 或 -
采取措施以解除对 32 位进程虚拟内存最大大小的体系结构约束
若要优化应用程序对托管内存资源的使用,请在 .NET 内存分配分析运行中收集托管内存分配数据。 请查看分析工具 .NET 内存数据视图报告以了解应用程序的内存分配模式。
使用“对象生存期”视图可以确定程序的哪些数据对象被保留在代中,然后从此处被回收。
使用 .NET 内存分配视图确定导致这些分配的执行路径。
有关如何提高垃圾回收性能的更多信息,请参见 MSDN 网站上的 .NET Framework 技术文章:Garbage Collector Basics and Performance Hints(垃圾回收器基础知识和性能提示)。
若要从对进程地址空间专用部分大小的虚拟内存约束获得体系结构释放,请尝试在 64 位计算机上运行此 32 位进程。 64 位计算机上的 32 位进程最多可以获取 4 GB 的专用虚拟内存。
64 位计算机上运行的 64 位进程最多可以获取 8 TB 的虚拟内存。 请考虑重新编译应用程序,以作为 64 位本机应用程序执行。 此规则仅供参考,无需进行更正操作。