성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[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 Internals Cookbook Part 12 - Memory structure, attributes, handles</h1> <p> 드디어 .NET Internals Cookbook 시리즈의 12번째 마지막 글입니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET Internals Cookbook Part 12 - Memory structure, attributes, handles ; <a target='tab' href='https://blog.adamfurmanek.pl/2019/05/04/net-internals-cookbook-part-12/'>https://blog.adamfurmanek.pl/2019/05/04/net-internals-cookbook-part-12/</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>82. 속성의 3가지 분류 - bit-mapped, custom, pseudo-custom</div> <br /> 속성은 IL 언어와의 관계에서 3가지로 분류됩니다. <br /> <br /> <ol> <li>Bit-mapped - C# 언어의 속성이 그대로 IL과 1:1 매핑되는 경우, 예를 들어 public</li> <li>Custom - 일반적인 특성, 예를 들어 사용자가 정의한 모든 특성</li> <li>Pseudo-custom - Custom 특성과 유사하지만 IL에 반영되는 특성, 예를 들어 Serializable</li> </ol> <br /> 이해를 돕기 위해 C# 코드와 그것의 IL 코드 번역을 보겠습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; <span style='color: blue; font-weight: bold'>[MyCustom]</span> <span style='color: blue; font-weight: bold'>[Serializable]</span> <span style='color: blue; font-weight: bold'>public</span> class Program { public static void Main() { } } class MyCustomAttribute : Attribute { public MyCustomAttribute() { } } </pre> <br /> 위에서 Program 타입에 지정한 MyCustom, Serializable, public 속성은 IL 코드에 다음과 같이 반영됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .class <span style='color: blue; font-weight: bold'>public</span> auto ansi <span style='color: blue; font-weight: bold'>serializable</span> beforefieldinit Program extends [mscorlib]System.Object { <span style='color: blue; font-weight: bold'>.custom instance void MyCustomAttribute::.ctor() = ( 01 00 00 00 )</span> .method public hidebysig static void Main () cil managed { .maxstack 8 .entrypoint IL_0000: nop IL_0001: ret } // end of method Program::Main .method public hidebysig specialname rtspecialname instance void .ctor () cil managed { .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: nop } // end of method Program::.ctor } // end of class Program </pre> <br /> 보는 바와 같이 public은 public으로 직접 매핑되므로 bit-mapped, C#의 클래스로 정의된 Serializable은 serializable로 지정되기 때문에 Pseudo-custom으로, MyCustom의 경우 IL 예약어로 번역되지 않고 ".custom instance void MyCustomAttribute::.ctor()"라는 별도 항목을 갖기 때문에 Custom으로 분류됩니다.<br /> <br /> Pseudo-custom에 대한 보다 자세한 사항은 다음의 글을 참고하세요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Subterranean IL: Pseudo custom attributes ; <a target='tab' href='https://www.red-gate.com/simple-talk/blogs/subterranean-il-pseudo-custom-attributes/'>https://www.red-gate.com/simple-talk/blogs/subterranean-il-pseudo-custom-attributes/</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>83. 핸들 재사용 공격이란?</div> <br /> 윈도우의 HANDLE은 프로세스(EXE)가 소유한 핸들 테이블에 대한 인덱스 번호입니다. 그렇다면, A라는 스레드가 Handle 값을 스택에 보관하고 스레드가 중지(suspend)되었다고 가정해 보겠습니다. 그때 다른 B 스레드가 해당 핸들을 닫아버리고(CloseHandle) 새로운 커널 객체를 생성하면 이전에 닫았던 동일한 핸들(인덱스 번호)이 재사용되는 것도 가능합니다. 만약 그런 상황이 발생했을 때 A 스레드가 다시 실행을 재개(resume), 스택에 보관했던 핸들을 사용하게 되면 의도치 않는 커널 자원을 사용하게 됩니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>84. .NET 세계에서의 Handle 자원의 종류는?</div> <br /> <ul> <li>Strong handle - 일반적인 참조(like a normal reference)</li> <li>Short weak handle - GC되는 것을 막지도 못하고 되살아난 경우에도 그것을 알수 없음(doesn’t stop the object from cleaning up, does not track the object if it is resurrected)</li> <li>Long weak handle - "Short weak handle"처럼 GC되는 것을 막지는 못하지만 되살아난 경우에는 알 수 있음(like short weak handle but tracks the object after it gets resurrected)</li> <li>Pinned handle - GC 도중 객체를 움직이지 못하도록 함(strong handle which doesn’t allow the object to be moved)</li> <li>Async pinned handle - Pinned 핸들과 같지만 GC는 해당 핸들이 async 동작 후 unpinned시킬 수 있다는 것을 알고 있음(like pinned handle but GC knows that it can be unpinned after async (typically I/O) operation is completed)</li> <li>Ref count handle - COM 연동 시처럼 그것의 참조 카운트가 유지되는 유형의 핸들(handle counting references, used for COM interop)</li> <li>Dependent handle - ConditionalWeakTable에 사용되는데, 2개의 객체를 strong handle로 연결하지만 외부적으로는 weak handle임(used by ConditionalWeakTable, connects two objects by strong handle, but from the outside is like a weak handle)</li> </ul> <br /> <br /> 아래는 windbg에서 devenv.exe를 대상으로 !gchandles를 수행한 경우의 결과를 보여줍니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:000> !gchandles ...[생략]... Total 62730 objects Handles: Strong Handles: 217 Pinned Handles: 134 Async Pinned Handles: 66 Ref Count Handles: 1240 Weak Long Handles: 2410 Weak Short Handles: 55019 Dependent Handles: 3644 </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>85. ref local이란?</div> <br /> <a target='tab' href='http://www.yes24.com/Product/Goods/73031673'>제 책</a>에서 C# 7.0의 "12.2 반환값 및 로컬 변수에 ref 기능 추가(ref returns and locals)"를 참고하세요. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>86. interior pointer란?</div> <br /> 예전에 Span을 설명하면서 <a target='tab' href='https://blog.ndepend.com/managed-pointers-span-ref-struct-c11-ref-fields-and-the-scoped-keyword/'>interior pointer</a>를 소개한 적이 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# 7.2 - Span<T> ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11534'>http://www.sysnet.pe.kr/2/0/11534</a> </pre> <br /> "interior pointer"는 객체의 내부를 가리키는 관리 포인터입니다. 예를 들어 다음의 코드를 보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; namespace Program { public class Program { public static void Main(string[] args) { var foo = new Foo(); foo.Bar = 5; <span style='color: blue; font-weight: bold'>ref int bar = ref foo.Bar;</span> Console.WriteLine(foo.Bar); Console.WriteLine(bar); foo.Bar = 6; Console.WriteLine(foo.Bar); Console.WriteLine(bar); bar = 7; Console.WriteLine(foo.Bar); Console.WriteLine(bar); } } } class Foo{ public int Bar; } </pre> <br /> foo 변수는 GC 힙 메모리 위치에서 Foo 타입의 인스턴스를 가리키고 있는 반면, bar 변수는 foo 변수의 위치가 아닌, 그 객체의 내부에 "int Bar" 필드의 위치를 가리키는 관리 포인터입니다. 유의할 것은, 같은 ref 지역 변수를 사용하는 구문이지만 어떤 것을 가리키느냐에 따라 interior pointer가 아닐 수도 있다는 점입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // interior pointer인 경우 ref int bar = ref foo.Bar; // foo 객체의 내부를 가리키므로 interior pointer // interior pointer가 아닌 경우 int a = 5; ref int bar = ref a; // 스택에 있는 로컬 변수를 가리키므로 interior pointer가 아님 </pre> <br /> 그렇다면, GC는 interior pointer의 참조로 인해 해당 객체를 제거해서는 안 된다는 것을 어떻게 알 수 있을까요? 이를 위해 힙 영역을 다중 블록으로 나눈 <a target='tab' href='http://www.sysnet.pe.kr/2/0/11878#tag64'>Brick table</a>이라는 것을 사용합니다. It contains an offset to the first object inside such a block so then it can traverse the chunk of memory and find the object which should be held by the interior pointer. 하지만 이 작업은 성능상 매우 좋지 않기 때문에 interior pointer는 스택에 존재하는 로컬 변수 반환 값으로만 사용하도록 제한되었습니다. 즉, 힙에 할당되는 클래스의 경우에는 다음과 같이 interior pointer를 포함하지 못합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > class Foo{ public <span style='color: blue; font-weight: bold'>ref int Bar</span>; } </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>87. ref struct란?</div> <br /> 다음의 글을 참고하세요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# 7.2 - 스택에만 생성할 수 있는 값 타입 지원 - "ref struct" ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11530'>http://www.sysnet.pe.kr/2/0/11530</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>88. unsafe struct란?</div> <br /> 사실 "unsafe struct"라는 아주 새로운 유형의 구조체가 있는 것은 아니고, 단지 내부에 unsafe 관련 코드가 사용되면 붙여야 하는 것뿐입니다.<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 int i; public static void Main() { } } <span style='color: blue; font-weight: bold'>unsafe struct</span> Vector { public /* 또는 여기서 unsafe를 붙이거나 */ void Do() { Program pg = new Program(); /* 또는 여기서 unsafe block을 붙이거나 */ fixed (int* ptr = &pg.i) { } } } </pre> <br /> 단지 원 글에서는 <a target='tab' href='http://www.sysnet.pe.kr/2/0/11556'>fixed size buffer 사용 구문</a>을 사용하는 경우,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <span style='color: blue; font-weight: bold'>unsafe struct</span> FixedBufferExample { public fixed int buffer[1024]; // This is a fixed buffer. } </pre> <br /> unsafe를 struct 수준에서만 붙일 수 있다는 특수성이 있는 것입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>89. readonly struct란?</div> <br /> 다음의 글을 참고하세요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# 7.2 - readonly 구조체 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11524'>http://www.sysnet.pe.kr/2/0/11524</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>90. unsafe 타입이란?</div> <br /> 원 글에서는 unsafe 코드를 사용하는 클래스라고 하지만 위에서 설명했듯이 struct에도 붙일 수 있으므로 "클래스 및 구조체"라고 확장해서 정의할 수 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>91. blittable 타입이란?</div> <br /> 다음의 글을 참고하세요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - blittable 타입이란? ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11557'>http://www.sysnet.pe.kr/2/0/11557</a> C# 7.3 - unmanaged(blittable) 제네릭 제약 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11558'>http://www.sysnet.pe.kr/2/0/11558</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>92. C++/CLI에서 비관리 class는 어떤 식으로 컴파일될까?</div> <br /> ref class와 unmanaged class를 사용하는 다음의 C++/CLI 코드를 빌드해 보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > #include "stdafx.h" #include <cstdio> using namespace System; ref class Foo { }; <span style='color: blue; font-weight: bold'>class Bar { };</span> void Baz() { System::Console::WriteLine("In managed function."); } #pragma managed(push, off) <span style='color: blue; font-weight: bold'>void Taz() { printf("In unmanaged function.\n"); } </span> #pragma managed(pop) int main(array<System::String ^> ^args) { Console::WriteLine(L"Hello World"); return 0; } </pre> <br /> ref class Foo 타입과 관리 코드를 포함하는 Baz, main 함수는 IL 코드로 번역이 되는 반면, 비관리 코드만을 포함한 Taz 함수와 class Bar는 C++ 함수로 번역되므로 IL 코드로 남지 않습니다.<br /> </h1><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
4488
(왼쪽의 숫자를 입력해야 합니다.)