본문 바로가기

.NET/Debugging

Windbg툴로 관리힙 메모리 디버깅하기 3


http://blogs.msdn.com/b/alejacma/archive/2009/08/13/managed-debugging-with-windbg-managed-heap-part-3.aspx


이글은 위의 내용을 토대로 했습니다. 위 내용과 상이한 부분이 있을수 있습니다.

이 장에서는 어던 object들이 어떤 object들을 참고하고 있는지 보도록 하겠습니다.

우리가 생각하기에 저 object들은 힙에서 없어져야하는데 왜 아직까지 남아있지 하는 그런 object들을 심심치 않게 볼수 있다. 왜냐면 뭘까요? 그건 다른 object들이 아직 그 object들을 참조하고 있을 거기 때문에 GC가 쓰레기 수집을 하지 않은것입니다.

GC는 application root라는 곳으로 시작해 object 참조 그래프를 그리는데 여기서 application root의 한 샘플을 보게 될겁니다.


0:000> !DumpHeap -stat

...

Statistics:

MT Count TotalSize Class Name

...

0ee10034 19218 7149096 ASP.lab3_1_aspx

...

Total 1748273 objects

0:000> !DumpHeap -mt 0ee10034

------------------------------

Heap 0

Address MT Size

...

0556b268 0ee10034 372

0556ccac 0ee10034 372

total 6524 objects

------------------------------

Heap 1

...

0:000> !GCRoot 0556b268

Note: Roots found on stacks may be false positives. Run "!help gcroot" for

more info.

Scan Thread 15 OSTHread 2c4

...

Scan Thread 13 OSTHread c4c

esi:Root:14f002dc(System.Web.HttpResponse)->

14f00194(System.Web.HttpContext)->

14f00a08(ASP.lab3_1_aspx)->

02b33d80(System.Web.Caching.Cache)->

02b33e60(System.Web.Caching.CacheMultiple)->

02b33e78(System.Object[])->

02b33e90(System.Web.Caching.CacheSingle)->

02b33f38(System.Web.Caching.CacheExpires)->

02b33f58(System.Object[])->

02b34878(System.Web.Caching.ExpiresBucket)->

10872ea0(System.Web.Caching.ExpiresPage[])->

094b5734(System.Web.Caching.ExpiresEntry[])->

0556bb94(System.Web.Caching.CacheEntry)->

0556bb74(System.Web.Caching.CacheItemRemovedCallback)->

0556b268(ASP.lab3_1_aspx)

Scan Thread 22 OSTHread 830

Scan Thread 23 OSTHread f7c


Lab3_1.aspx페이지의 소스코드를 보면 우리는 왜 이 page가 cache object로 메모리에 계속 있는지 알수 있을겁니다.

public partial class Lab3_1 : System.Web.UI.Page

{

public void RemovedCallback(String k, Object v, System.Web.Caching.CacheItemRemovedReason r)

{

//do stuff when the item is removed

}

protected void Page_Load(object sender, EventArgs e)

{

UserInfo u = new UserInfo("James", "Dean", "MainStreet 21, NY");

Cache.Add(Guid.NewGuid().ToString(), u, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 5, 0), System.Web.Caching.CacheItemPriority.NotRemovable, new System.Web.Caching.CacheItemRemovedCallback(this.RemovedCallback));

}

}


참조객체는 여러군데에 존재할수 있다.
1. 레지스트리 스레드

0:022> !gcroot 0x14ef2a34

esi:Root: 14f002dc(System.Web.HttpResponse)->

…->

14ef2a34(ASP.lab3_1_aspx)


2.스택 스레드

ESP:ef4f610:Root: 14f00194(System.Web.HttpContext)->

… ->

14ef2a34(ASP.lab3_1_aspx)


3. GCHandle
 - 여러종류의 handle들이 우리의 object를 참조하고 할수 있다.
   - Strong Handles : 핸들들이 강제적으로 해제되기 전까지 object들을 메모리안에 잡아둔다. 일반적으로static 변수
   - Pinned Handles : GC가 일어났을때 다음세대로 이동못하게 빈박아 넣는다. 이건 힙에 조각화를 야기할수 있다.(조심히 써야함)
   - Weak Short Handles : 참조하고 있는 object들이 계속 살아 있으면 null이 아니고 그렇지않으면 null이됨
   - Weak Short Handles : 참조하고 있는 object들이 메모리 재요청이 일어나지 않았을때만 null이 아님. 다시 살아날수도 있음.


아피곤하네요 ....나머지는 원문 참조해주시고요 일단 명령어 많이 날려봐서 익숙해 져야겠네요 져도 열라 날리고 있음 아직 많이 부족함...