在第二部分我们主要介绍针对各种内存问题的主要调试方式。在开始之前我还是推荐一个常规的调试步骤。
Part1我们提到过debugdiag工具以及如何通过其内建的rule来分析dump。
- 收集dump
- 通过DebugDiag选择Managed Memory Analysis规则来做一遍分析
- 根据DebugDiag分析报告通过windbg打开dump查看更多信息
大数据量datatable
首先尝试重现问题,写代码创建一张大表。
using System;
using System.Data;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CreateLargeDataTables();
Response.Write("Large Datatable, enjoy!");
}
void CreateLargeDataTables()
{
DataTable table = new DataTable();
for (int i = 0; i < 100; i++)
{
table.Columns.Add(string.Format("Column{0}", i));
}
for (int i = 0; i < 1000; i++)
{
DataRow row = table.NewRow();
for (int j = 0; j < 100; j++)
{
row[j] = string.Format("Column{0}Row{1}", i, j);
for (int k = 0; k < 100; k++)
{
row[j] += "StringConcatCauseHighMemoryAndHighCPU";
}
}
table.Rows.Add(row);
}
Application.Add("datatable", table);
}
}
将aspx网页部署到IIS,IE请求该网页。打开TaskManager观察内存使用情况。
内存使用量在持续增长,请求结束之后趋于平稳。
IIS Worker Process内存使用两805.8M。
我只发了一个请求。
可以肯定IIS WorkerProcess (w3wp.exe)中内存使用有些异常。直接抓一个full user dump (可以直接在TaskManage右键选择CreateDumpFile)。
通过Windbg打开Dump分析。
我从DebugDiag的安装目录C:\Program Files\DebugDiag\Exts\拷贝了psscor2到windbg的安装目录下,这样我就可以直接执行接下来的命令来加载psscor2这个强悍的托管代码调试扩展。
0:000>.load psscor2
用Address命令看一下内存总体使用情况,可以看到<unclassified>占用量最大,调试.NET程序大多数时候<unclassified>对应.NET的托管堆大小。所以我们目标明确了,问题的确出来托管堆里面。