성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
[정성태] The Windows Registry Adventure #1: ...
[정성태] systemd for Developers I ; https:/...
[정성태] 엄밀히 object 타입의 인스턴스가 다른 타입으로 형변환 가능...
[정성태] 아래의 글에서 나오는 "Windows Application Pa...
[정성태] The history of calling conventions,...
[정성태] Secure and Deploy .NET Windows Form...
[정성태] Get Started with Milvus Vector DB i...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>.NET GC - 하위 세대의 객체를 포함하는 상위 세대의 참조를 추적하기 위한 card-table</h1> <p> GC의 동작 원리에 대해 쉽게 설명한 시리즈 글이 있어서 소개합니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Back to basic: Series on dynamic memory management ; <a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basic-series-on-dynamic-memory-management'>https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basic-series-on-dynamic-memory-management</a> </pre> <br /> 위의 글을 시작으로 현재 9개의 글이 쓰여졌는데 나름 재미있습니다.<br /> <br /> <ol> <li><a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-memory-allocation-a-walk-down-the-history'>Memory allocation, a walk down the history</a></li> <li>Why use garbage collection</li> <li><a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-reference-counting-garbage-collection'>Reference Counting Garbage Collection</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-mark-and-sweep-garbage-collection'>Mark-sweep garbage collection</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-copying-garbage-collection'>Copying garbage collection</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-optimizing-reference-counting-garbage-collection'>Optimizing reference counting garbage collection</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-handling-overflow-in-mark-stage'>Handling overflow in mark stage</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-generational-garbage-collection'>Generational Garbage Collection</a></li> <li><a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-how-does-the-gc-find-object-references'>How does the GC find object references</a></li> </ol> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - 생성한 참조 개체가 언제 GC의 정리 대상이 될까요? ; <a href='https://www.sysnet.pe.kr/2/0/13052'>https://www.sysnet.pe.kr/2/0/13052</a> </pre> <br /> 이 중에서 Young 세대의 객체가 Old 세대의 객체에 할당된 경우, 그것을 추적하기 위한 방법을 설명한 "<a target='tab' href='https://learn.microsoft.com/en-us/archive/blogs/abhinaba/back-to-basics-generational-garbage-collection'>Generational Garbage Collection</a>" 글을 읽으면서 확인하고 싶은 것이 생겼습니다.<br /> <br /> 위의 설명에 의하면, 아래와 같은 대입이 발생하는 경우 Card-table에 대한 액세스를 하기 위한 부가적인 호출이 JIT 컴파일러에 의해 삽입되어야 합니다. (글에 보면, .NET JITer가 그런 코드를 추가한다고 합니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > class Program { public InnerType In; static void Main(string[] args) { Program pg = new Program(); InnerType instance = new InnerType(); <span style='color: blue; font-weight: bold'>pg.In = instance;</span> } } class InnerType { } </pre> <br /> 실제로 그런지 어디 테스트 해볼까요? 비교를 위해 위의 코드를 다음과 같이 확장해 보겠습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > class Program { public InnerType In; public int valueIn; static void Main(string[] args) { Program pg = new Program(); InnerType stackVar = null; InnerType instance = new InnerType(); InnerType stackInstance = new InnerType(); pg.In = instance; <span style='color: blue; font-weight: bold'> pg.valueIn = 5; stackVar = stackInstance;</span> } } class InnerType { } </pre> <br /> "pg.valueIn = 5" 코드는 참조형이 아니기 때문에 card-table에 대한 액세스 코드가 없어야 합니다. 또한 "stackVar = stackInstance" 대입도 스택 변수에 할당되는 것이므로 역시 card-table 액세스 코드는 없어야 합니다.<br /> <br /> 이제 빌드하고, Visual Studio에서 Disassembly 창을 통해 확인해 보면? ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > pg.In = instance; 02B900E5 mov edx,dword ptr [ebp-40h] 02B900E8 mov eax,dword ptr [ebp-48h] 02B900EB lea edx,[edx+4] <span style='color: blue; font-weight: bold'>02B900EE call clr!JIT_WriteBarrierEAX (73711B70)</span> pg.valueIn = 5; 02B900F3 mov eax,dword ptr [ebp-40h] 02B900F6 mov dword ptr [eax+8],5 stackVar = stackInstance; 02B900FD mov eax,dword ptr [ebp-4Ch] 02B90100 mov dword ptr [ebp-44h],eax </pre> <br /> 정말 그렇군요. 아마도 저 호출이 card-table에 표시를 하기 위한 CLR 내부 코드로의 호출이지 않을까 예상해봅니다. 가끔, 관리 코드를 어셈블리 수준에서 디버깅하다 보면 저런 이상한 호출들이 끼워져 있는 것을 볼 수 있었는데, 이제야 그 원인을 이해하게 되었군요. ^^<br /> <br /> 간단한 테스트였지만... 역시나 '마법은 없다'는 것!<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6818
(왼쪽의 숫자를 입력해야 합니다.)