Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 3개 있습니다.)
(시리즈 글이 4개 있습니다.)
.NET Framework: 435. .NET GC - 하위 세대의 객체를 포함하는 상위 세대의 참조를 추적하기 위한 card-table
; https://www.sysnet.pe.kr/2/0/1670

.NET Framework: 458. 닷넷 GC가 순환 참조를 해제할 수 있을까요?
; https://www.sysnet.pe.kr/2/0/1740

.NET Framework: 2005. C# - 생성한 참조 개체가 언제 GC의 정리 대상이 될까요?
; https://www.sysnet.pe.kr/2/0/13052

.NET Framework: 2006. C# - GC.KeepAlive 메서드의 역할
; https://www.sysnet.pe.kr/2/0/13053




.NET GC - 하위 세대의 객체를 포함하는 상위 세대의 참조를 추적하기 위한 card-table

GC의 동작 원리에 대해 쉽게 설명한 시리즈 글이 있어서 소개합니다. ^^

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

위의 글을 시작으로 현재 9개의 글이 쓰여졌는데 나름 재미있습니다.

  1. Memory allocation, a walk down the history
  2. Why use garbage collection
  3. Reference Counting Garbage Collection
  4. Mark-sweep garbage collection
  5. Copying garbage collection
  6. Optimizing reference counting garbage collection
  7. Handling overflow in mark stage
  8. Generational Garbage Collection
  9. How does the GC find object references

C# - 생성한 참조 개체가 언제 GC의 정리 대상이 될까요?
; https://www.sysnet.pe.kr/2/0/13052

이 중에서 Young 세대의 객체가 Old 세대의 객체에 할당된 경우, 그것을 추적하기 위한 방법을 설명한 "Generational Garbage Collection" 글을 읽으면서 확인하고 싶은 것이 생겼습니다.

위의 설명에 의하면, 아래와 같은 대입이 발생하는 경우 Card-table에 대한 액세스를 하기 위한 부가적인 호출이 JIT 컴파일러에 의해 삽입되어야 합니다. (글에 보면, .NET JITer가 그런 코드를 추가한다고 합니다.)

class Program
{
    public InnerType In;

    static void Main(string[] args)
    {
        Program pg = new Program();
        InnerType instance = new InnerType();

        pg.In = instance;
    }
}

class InnerType
{
}

실제로 그런지 어디 테스트 해볼까요? 비교를 위해 위의 코드를 다음과 같이 확장해 보겠습니다.

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;

        pg.valueIn = 5;
        stackVar = stackInstance;
    }
}

class InnerType
{
}

"pg.valueIn = 5" 코드는 참조형이 아니기 때문에 card-table에 대한 액세스 코드가 없어야 합니다. 또한 "stackVar = stackInstance" 대입도 스택 변수에 할당되는 것이므로 역시 card-table 액세스 코드는 없어야 합니다.

이제 빌드하고, Visual Studio에서 Disassembly 창을 통해 확인해 보면? ^^

        pg.In = instance;
02B900E5  mov         edx,dword ptr [ebp-40h]  
02B900E8  mov         eax,dword ptr [ebp-48h]  
02B900EB  lea         edx,[edx+4]  
02B900EE  call    clr!JIT_WriteBarrierEAX (73711B70)

        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

정말 그렇군요. 아마도 저 호출이 card-table에 표시를 하기 위한 CLR 내부 코드로의 호출이지 않을까 예상해봅니다. 가끔, 관리 코드를 어셈블리 수준에서 디버깅하다 보면 저런 이상한 호출들이 끼워져 있는 것을 볼 수 있었는데, 이제야 그 원인을 이해하게 되었군요. ^^

간단한 테스트였지만... 역시나 '마법은 없다'는 것!




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

[연관 글]






[최초 등록일: ]
[최종 수정일: 11/23/2022]

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

비밀번호

댓글 작성자
 




... 46  47  48  49  50  51  52  53  54  55  56  57  [58]  59  60  ...
NoWriterDateCnt.TitleFile(s)
12582정성태3/29/202123196오류 유형: 709. Visual C++ - 컴파일 에러 error C2059: syntax error: '__stdcall'
12581정성태3/28/202123307.NET Framework: 1031. WinForm/WPF에서 Console 창을 띄워 출력하는 방법 (2) - Output 디버깅 출력을 AllocConsole로 우회 [2]
12580정성태3/28/202120788오류 유형: 708. SQL Server Management Studio - Execution Timeout Expired.
12579정성태3/28/202121567오류 유형: 707. 중첩 가상화(Nested Virtualization) - The virtual machine could not be started because this platform does not support nested virtualization.
12578정성태3/27/202122219개발 환경 구성: 560. Docker Desktop for Windows 기반의 Kubernetes 구성 (2) - WSL 2 인스턴스에 kind가 구성한 k8s 서비스 위치
12577정성태3/26/202122903개발 환경 구성: 559. Docker Desktop for Windows 기반의 Kubernetes 구성 - WSL 2 인스턴스에 kind 도구로 k8s 클러스터 구성
12576정성태3/25/202121648개발 환경 구성: 558. Docker Desktop for Windows에서 DockerDesktopVM 기반의 Kubernetes 구성 (2) - k8s 서비스 위치
12575정성태3/24/202120711개발 환경 구성: 557. Docker Desktop for Windows에서 DockerDesktopVM 기반의 Kubernetes 구성 [1]
12574정성태3/23/202126161.NET Framework: 1030. C# Socket의 Close/Shutdown 동작 (동기 모드)
12573정성태3/22/202123381개발 환경 구성: 556. WSL 인스턴스 초기 설정 명령어 [1]
12572정성태3/22/202122583.NET Framework: 1029. C# - GC 호출로 인한 메모리 압축(Compaction)을 확인하는 방법파일 다운로드1
12571정성태3/21/202119610오류 유형: 706. WSL 2 기반으로 "Enable Kubernetes" 활성화 시 초기화 실패 [1]
12570정성태3/19/202126427개발 환경 구성: 555. openssl - CA로부터 인증받은 새로운 인증서를 생성하는 방법
12569정성태3/18/202125954개발 환경 구성: 554. WSL 인스턴스 export/import 방법 및 단축 아이콘 설정 방법
12568정성태3/18/202118511오류 유형: 705. C# 빌드 - Couldn't process file ... due to its being in the Internet or Restricted zone or having the mark of the web on the file.
12567정성태3/17/202121711개발 환경 구성: 553. Docker Desktop for Windows를 위한 k8s 대시보드 활성화 [1]
12566정성태3/17/202121431개발 환경 구성: 552. Kubernetes - kube-apiserver와 REST API 통신하는 방법 (Docker Desktop for Windows 환경)
12565정성태3/17/202117985오류 유형: 704. curl.exe 실행 시 dll not found 오류
12564정성태3/16/202118654VS.NET IDE: 160. 새 프로젝트 창에 C++/CLI 프로젝트 템플릿이 없는 경우
12563정성태3/16/202121626개발 환경 구성: 551. C# - JIRA REST API 사용 정리 (3) jira-oauth-cli 도구를 이용한 키 관리
12562정성태3/15/202121822개발 환경 구성: 550. C# - JIRA REST API 사용 정리 (2) JIRA OAuth 토큰으로 API 사용하는 방법파일 다운로드1
12561정성태3/12/202120807VS.NET IDE: 159. Visual Studio에서 개행(\n, \r) 등의 제어 문자를 치환하는 방법 - 정규 표현식 사용
12560정성태3/11/202122280개발 환경 구성: 549. ssh-keygen으로 생성한 PKCS#1 개인키/공개키 파일을 각각 PKCS8/PEM 형식으로 변환하는 방법
12559정성태3/11/202123067.NET Framework: 1028. 닷넷 5 환경의 Web API에 OpenAPI 적용을 위한 NSwag 또는 Swashbuckle 패키지 사용 [2]파일 다운로드1
12558정성태3/10/202121907Windows: 192. Power Automate Desktop (Preview) 소개 - Bitvise SSH Client 제어 [1]
12557정성태3/10/202119871Windows: 191. 탐색기의 보안 탭에 있는 "Object name" 경로에 LEFT-TO-RIGHT EMBEDDING 제어 문자가 포함되는 문제
... 46  47  48  49  50  51  52  53  54  55  56  57  [58]  59  60  ...