Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 12개 있습니다.)
.NET Framework: 811. (번역글) .NET Internals Cookbook Part 1 - Exceptions, filters and corrupted processes
; https://www.sysnet.pe.kr/2/0/11838

.NET Framework: 816. (번역글) .NET Internals Cookbook Part 2 - GC-related things
; https://www.sysnet.pe.kr/2/0/11869

.NET Framework: 818. (번역글) .NET Internals Cookbook Part 3 - Initialization tricks
; https://www.sysnet.pe.kr/2/0/11871

.NET Framework: 819. (번역글) .NET Internals Cookbook Part 4 - Type members
; https://www.sysnet.pe.kr/2/0/11872

.NET Framework: 820. (번역글) .NET Internals Cookbook Part 5 - Methods, parameters, modifiers
; https://www.sysnet.pe.kr/2/0/11873

.NET Framework: 821. (번역글) .NET Internals Cookbook Part 6 - Object internals
; https://www.sysnet.pe.kr/2/0/11874

.NET Framework: 822. (번역글) .NET Internals Cookbook Part 7 - Word tearing, locking and others
; https://www.sysnet.pe.kr/2/0/11876

.NET Framework: 823. (번역글) .NET Internals Cookbook Part 8 - C# gotchas
; https://www.sysnet.pe.kr/2/0/11877

.NET Framework: 824. (번역글) .NET Internals Cookbook Part 9 - Finalizers, queues, card tables and other GC stuff
; https://www.sysnet.pe.kr/2/0/11878

.NET Framework: 825. (번역글) .NET Internals Cookbook Part 10 - Threads, Tasks, asynchronous code and others
; https://www.sysnet.pe.kr/2/0/11879

.NET Framework: 826. (번역글) .NET Internals Cookbook Part 11 - Various C# riddles
; https://www.sysnet.pe.kr/2/0/11882

.NET Framework: 831. (번역글) .NET Internals Cookbook Part 12 - Memory structure, attributes, handles
; https://www.sysnet.pe.kr/2/0/11891




(번역글) .NET Internals Cookbook Part 12 - Memory structure, attributes, handles

드디어 .NET Internals Cookbook 시리즈의 12번째 마지막 글입니다. ^^

.NET Internals Cookbook Part 12 - Memory structure, attributes, handles
; https://blog.adamfurmanek.pl/2019/05/04/net-internals-cookbook-part-12/





82. 속성의 3가지 분류 - bit-mapped, custom, pseudo-custom

속성은 IL 언어와의 관계에서 3가지로 분류됩니다.

  1. Bit-mapped - C# 언어의 속성이 그대로 IL과 1:1 매핑되는 경우, 예를 들어 public
  2. Custom - 일반적인 특성, 예를 들어 사용자가 정의한 모든 특성
  3. Pseudo-custom - Custom 특성과 유사하지만 IL에 반영되는 특성, 예를 들어 Serializable

이해를 돕기 위해 C# 코드와 그것의 IL 코드 번역을 보겠습니다.

using System;

[MyCustom]
[Serializable]
public class Program
{
    public static void Main()
    {
    }
}

class MyCustomAttribute : Attribute
{
    public MyCustomAttribute() { }
}

위에서 Program 타입에 지정한 MyCustom, Serializable, public 속성은 IL 코드에 다음과 같이 반영됩니다.

.class public auto ansi serializable beforefieldinit Program
	extends [mscorlib]System.Object
{
	.custom instance void MyCustomAttribute::.ctor() = (
        01 00 00 00
    )
	.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

보는 바와 같이 public은 public으로 직접 매핑되므로 bit-mapped, C#의 클래스로 정의된 Serializable은 serializable로 지정되기 때문에 Pseudo-custom으로, MyCustom의 경우 IL 예약어로 번역되지 않고 ".custom instance void MyCustomAttribute::.ctor()"라는 별도 항목을 갖기 때문에 Custom으로 분류됩니다.

Pseudo-custom에 대한 보다 자세한 사항은 다음의 글을 참고하세요.

Subterranean IL: Pseudo custom attributes
; https://www.red-gate.com/simple-talk/blogs/subterranean-il-pseudo-custom-attributes/





83. 핸들 재사용 공격이란?

윈도우의 HANDLE은 프로세스(EXE)가 소유한 핸들 테이블에 대한 인덱스 번호입니다. 그렇다면, A라는 스레드가 Handle 값을 스택에 보관하고 스레드가 중지(suspend)되었다고 가정해 보겠습니다. 그때 다른 B 스레드가 해당 핸들을 닫아버리고(CloseHandle) 새로운 커널 객체를 생성하면 이전에 닫았던 동일한 핸들(인덱스 번호)이 재사용되는 것도 가능합니다. 만약 그런 상황이 발생했을 때 A 스레드가 다시 실행을 재개(resume), 스택에 보관했던 핸들을 사용하게 되면 의도치 않는 커널 자원을 사용하게 됩니다.





84. .NET 세계에서의 Handle 자원의 종류는?

  • Strong handle - 일반적인 참조(like a normal reference)
  • Short weak handle - GC되는 것을 막지도 못하고 되살아난 경우에도 그것을 알수 없음(doesn’t stop the object from cleaning up, does not track the object if it is resurrected)
  • Long weak handle - "Short weak handle"처럼 GC되는 것을 막지는 못하지만 되살아난 경우에는 알 수 있음(like short weak handle but tracks the object after it gets resurrected)
  • Pinned handle - GC 도중 객체를 움직이지 못하도록 함(strong handle which doesn’t allow the object to be moved)
  • 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)
  • Ref count handle - COM 연동 시처럼 그것의 참조 카운트가 유지되는 유형의 핸들(handle counting references, used for COM interop)
  • 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)


아래는 windbg에서 devenv.exe를 대상으로 !gchandles를 수행한 경우의 결과를 보여줍니다.

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





85. ref local이란?

제 책에서 C# 7.0의 "12.2 반환값 및 로컬 변수에 ref 기능 추가(ref returns and locals)"를 참고하세요. ^^





86. interior pointer란?

예전에 Span을 설명하면서 interior pointer를 소개한 적이 있습니다.

C# 7.2 - Span<T>
; https://www.sysnet.pe.kr/2/0/11534

"interior pointer"는 객체의 내부를 가리키는 관리 포인터입니다. 예를 들어 다음의 코드를 보면,

using System;

namespace Program
{
    public class Program
    {   
        public static void Main(string[] args)
        {
            var foo = new Foo();
            foo.Bar = 5;
            ref int bar = ref foo.Bar;
            
            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;
}

foo 변수는 GC 힙 메모리 위치에서 Foo 타입의 인스턴스를 가리키고 있는 반면, bar 변수는 foo 변수의 위치가 아닌, 그 객체의 내부에 "int Bar" 필드의 위치를 가리키는 관리 포인터입니다. 유의할 것은, 같은 ref 지역 변수를 사용하는 구문이지만 어떤 것을 가리키느냐에 따라 interior pointer가 아닐 수도 있다는 점입니다.

// interior pointer인 경우 
ref int bar = ref foo.Bar; // foo 객체의 내부를 가리키므로 interior pointer

// interior pointer가 아닌 경우
int a = 5;
ref int bar = ref a; // 스택에 있는 로컬 변수를 가리키므로 interior pointer가 아님

그렇다면, GC는 interior pointer의 참조로 인해 해당 객체를 제거해서는 안 된다는 것을 어떻게 알 수 있을까요? 이를 위해 힙 영역을 다중 블록으로 나눈 Brick table이라는 것을 사용합니다. 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를 포함하지 못합니다.

class Foo{
    public ref int Bar;
}





87. ref struct란?

다음의 글을 참고하세요.

C# 7.2 - 스택에만 생성할 수 있는 값 타입 지원 - "ref struct"
; https://www.sysnet.pe.kr/2/0/11530





88. unsafe struct란?

사실 "unsafe struct"라는 아주 새로운 유형의 구조체가 있는 것은 아니고, 단지 내부에 unsafe 관련 코드가 사용되면 붙여야 하는 것뿐입니다.

class Program
{
    public int i;

    public static void Main()
    {
    }
}

unsafe struct Vector
{
    public /* 또는 여기서 unsafe를 붙이거나 */ void Do()
    {
        Program pg = new Program();

        /* 또는 여기서 unsafe block을 붙이거나 */
        fixed (int* ptr = &pg.i)
        {
        }
    }
}

단지 원 글에서는 fixed size buffer 사용 구문을 사용하는 경우,

unsafe struct FixedBufferExample
{
    public fixed int buffer[1024]; // This is a fixed buffer.
}

unsafe를 struct 수준에서만 붙일 수 있다는 특수성이 있는 것입니다.





89. readonly struct란?

다음의 글을 참고하세요.

C# 7.2 - readonly 구조체
; https://www.sysnet.pe.kr/2/0/11524





90. unsafe 타입이란?

원 글에서는 unsafe 코드를 사용하는 클래스라고 하지만 위에서 설명했듯이 struct에도 붙일 수 있으므로 "클래스 및 구조체"라고 확장해서 정의할 수 있습니다.





91. blittable 타입이란?

다음의 글을 참고하세요.

C# - blittable 타입이란?
; https://www.sysnet.pe.kr/2/0/11557

C# 7.3 - unmanaged(blittable) 제네릭 제약
; https://www.sysnet.pe.kr/2/0/11558





92. C++/CLI에서 비관리 class는 어떤 식으로 컴파일될까?

ref class와 unmanaged class를 사용하는 다음의 C++/CLI 코드를 빌드해 보면,

#include "stdafx.h"
#include <cstdio>

using namespace System;

ref class Foo {
};

class Bar {
};

void Baz() {
    System::Console::WriteLine("In managed function.");
}

#pragma managed(push, off)
void Taz() {
    printf("In unmanaged function.\n");
}

#pragma managed(pop)

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Hello World");
    return 0;
}

ref class Foo 타입과 관리 코드를 포함하는 Baz, main 함수는 IL 코드로 번역이 되는 반면, 비관리 코드만을 포함한 Taz 함수와 class Bar는 C++ 함수로 번역되므로 IL 코드로 남지 않습니다.



[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 4/19/2024]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  127  128  129  130  131  132  133  [134]  135  ...
NoWriterDateCnt.TitleFile(s)
1738정성태8/23/201423384.NET Framework: 456. C# - CAS를 이용한 Lock 래퍼 클래스파일 다운로드1
1737정성태8/20/201420838VS.NET IDE: 93. Visual Studio 2013 동기화 문제
1736정성태8/19/201426862VC++: 79. [부연] CAS Lock 알고리즘은 과연 빠른가? [2]파일 다운로드1
1735정성태8/19/201419372.NET Framework: 455. 닷넷 사용자 정의 예외 클래스의 최소 구현 코드 - 두 번째 이야기
1734정성태8/13/201421109오류 유형: 237. Windows Media Player cannot access the file. The file might be in use, you might not have access to the computer where the file is stored, or your proxy settings might not be correct.
1733정성태8/13/201427371.NET Framework: 454. EmptyWorkingSet Win32 API를 사용하는 C# 예제파일 다운로드1
1732정성태8/13/201435722Windows: 99. INetCache 폴더가 다르게 보이는 이유
1731정성태8/11/201428165개발 환경 구성: 235. 점(.)으로 시작하는 파일명을 탐색기에서 만드는 방법
1730정성태8/11/201423371개발 환경 구성: 234. Royal TS의 터미널(Terminal) 연결에서 한글이 깨지는 현상 해결 방법
1729정성태8/11/201419349오류 유형: 236. SqlConnection - The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly.
1728정성태8/8/201431589.NET Framework: 453. C# - 오피스 파워포인트(Powerpoint) 파일을 WinForm에서 보는 방법파일 다운로드1
1727정성태8/6/201421777오류 유형: 235. SignalR 오류 메시지 - Counter 'Messages Bus Messages Published Total' does not exist in the specified Category. [2]
1726정성태8/6/201420634오류 유형: 234. IIS Express에서 COM+ 사용 시 SecurityException - "Requested registry access is not allowed" 발생
1725정성태8/6/201422575오류 유형: 233. Visual Studio 2013 Update3 적용 후 Microsoft.VisualStudio.Web.PageInspector.Runtime 모듈에 대한 FileNotFoundException 예외 발생
1724정성태8/5/201427420.NET Framework: 452. .NET System.Threading.Thread 개체에서 Native Thread Id를 구하는 방법 - 두 번째 이야기 [1]파일 다운로드1
1723정성태7/29/201459786개발 환경 구성: 233. DirectX 9 예제 프로젝트 빌드하는 방법 [3]파일 다운로드1
1722정성태7/25/201422131오류 유형: 232. IIS 500 Internal Server Error - NTFS 암호화된 폴더에 웹 애플리케이션이 위치한 경우
1721정성태7/24/201425428.NET Framework: 451. 함수형 프로그래밍 개념 - 리스트 해석(List Comprehension)과 순수 함수 [2]
1720정성태7/23/201423395개발 환경 구성: 232. C:\WINDOWS\system32\LogFiles\HTTPERR 폴더에 로그 파일을 남기지 않는 설정
1719정성태7/22/201427236Math: 13. 동전을 여러 더미로 나누는 경우의 수 세기(Partition Number) - 두 번째 이야기파일 다운로드1
1718정성태7/19/201436667Math: 12. HTML에서 수학 관련 기호/수식을 표현하기 위한 방법 - MathJax.js [4]
1716정성태7/17/201436370개발 환경 구성: 231. PC 용 무료 안드로이드 에뮬레이터 - genymotion
1715정성태7/13/201431465기타: 47. 운영체제 종료 후에도 USB 외장 하드의 전원이 꺼지지 않는 경우 [3]
1714정성태7/11/201421547VS.NET IDE: 92. Visual Studio 2013을 지원하는 IL Support 확장 도구
1713정성태7/11/201445310Windows: 98. 윈도우 시스템 디스크 용량 확보를 위한 "Package Cache" 폴더 이동 [1]
1712정성태7/10/201433847.NET Framework: 450. 영문 윈도우에서 C# 콘솔 프로그램의 유니코드 출력 방법 [3]
... 121  122  123  124  125  126  127  128  129  130  131  132  133  [134]  135  ...