在正在运行的进程中检测类的未处理实例?

时间:2011-06-06 00:23:12

标签: .net debugging windbg

我有一个在w3wp.exe中运行的IIS应用程序。我不是百分之百确定我的某个类是否被处置并且随着时间的推移增加了内存占用(仅查看任务管理器中的内存使用情况并不可靠)。

是否有一种简单的方法来获取内存转储(在Win2008中通过任务管理器很容易),将其加载到WinDbg或Visual Studio中,然后询问“这个内存转储中有多少个Foo.Bar实例?” / p>

我知道我可以/应该使用Memory Profiler,但我现在没有这个选项,因为它是一个生产系统。

2 个答案:

答案 0 :(得分:4)

  

是否有一种记忆的简单方法   转储(在Win2008中很容易,通过   任务管理器),将其加载到WinDbg或   Visual Studio,然后问“有多少   Foo.Bar的实例就在这里   内存转储?

您可以使用Proc Dump来获取内存转储。

在WinDbg中,!dumpheap –stat将按类型

为您提供分配

如果您使用!dumpheap -type Foo.Bar,您应该只获得以Foo.Bar开头的类

有关详细信息,请参阅SOS.dll (SOS Debugging Extension)

答案 1 :(得分:1)

您可以使用具有终结器和处置方法的装饰器类,并在错过的处置时提醒您。所以,如果你的课程是这样的:

public class CustomerTracker
{
   public bool IsNew() {...}
}

然后定义一个接口并使客户端代码使用它:

public interface ICustomerTracker
{
   public bool IsNew();
}

定义装饰器并在创建任何这些对象的地方使用它:

public class CustomerTrackerMemDecorator : ICustomerTracker
{
   ICustomrTracker tracker;

    CustomerTrackerMemDecorator (ICustomrTracker tracker)
    {
            this.tracker = tracker;
    }

    public bool IsNew() { return tracker.IsNew(); }

    ~CustomerTrackerMemDecorator
    {
            Debug.Assert("Missed dispose found!");
    }

    public override Dispose()
    {
            tracker.Dispose();
            GC.SupressFinalize(this);
    }
}

然后你在哪里:

CustomerTracker tracker = new CustomerTracker();

替换为

ICustomerTracker tracker = new CustomerTrackerMemDecorator(new CustomerTracker());