[2022. 03. 07. Mon]
※ 개인 학습 기록용입니다. 개념이나 예시가 잘못 되었을 수도 있음을 주의드립니다. 만약에 그러한 점이 발견되었다면 조언 및 첨삭 감사히 부탁드리겠습니다 :)
■ 개념
여러가지 뜻이 존재하지만 위 패턴에서 사용되어지는 개념은 Dispose : 처분하다, 처리하다. 이다.
able이 붙은 Disposable은 처분 가능하다는 뜻인데 무엇을 처분하는 것인지를 먼저 이해를 해야 사용할 수 있다.
https://docs.microsoft.com/ko-kr/dotnet/api/system.idisposable?view=net-6.0 (참고 자료)
바로 메모리를 관리하는 패턴인데. 처음에 해당 자료를 봤을 때는
'C#에는 .NET Framework안에서 자동으로 리소스를 관리해주기 때문에 C#자체가 managed code를 생성하지 않나? 그렇기 때문에 그 코드로 만들어진 리소스는 managed resource가 되어야 하지 않나? 그래서 unmanaged code란 대체 무엇을 의미하는 것인가??' 의문이 들어 자료를 더 찾아봤다.
참고 1 : https://www.partech.nl/en/publications/2021/03/managed-and-unmanaged-code---key-differences
■ UnManaged Code
1. 이름 그대로 관리되어지지 않는 코드이다.
2. 컴파일 할 때 '바로 그 컴퓨터에 적합한' 기계 코드를 생성한다.
(IL과 같은 중간과정을 거치지 않는다.)
3. Managed code는 Runtime이 알아서 메모리 관리를 해주는 반면에, Unmanaged는 사용자에게 그 책임이 있다.
4. MFC, ATL, Win32 등으로 생성되는 프로젝트는 모두 UnManaged Application이다.
(반면에 Visual C++는 사용자가 원하면 managed, unmanaged를 선택해 설계할 수 있다.)
[ 단점 ]
- Security is not provided to the application
- 보안이 취약할 수 있다.
- The programmer has to do exception handling
- 프로그래머가 예외 처리 핸들링을 직접 해야한다.
- No automatic implementation of garbage collection
- 가비지 컬렉션을 수동으로 해줘야한다.
- Making use of unsafe code can lead to errors that might occur as type checking is bypassed.
- 타입 체킹의 우회로 인한 에러를 뱉어낼 수 있다.
■ Managed Code
1. 먼저 Managed code는 이름 그대로 관리되어진 코드이다.
2. .Net Framework와 특정 컴파일러들이 만들어낸 코드이다.
3. 컴파일러들은 우선 IL(Intermediate Language - 중간언어)라고 불리는 코드를 생성한다.
4. 위와 같이 생성된 IL코드들은 Assembly라는 파일에 Meta데이터와 같이 함께 저장된다.
5. Meta데이터에는 컴파일한 코드들의 클래스, 함수 그리고 변수 등의 속성 등을 가진다.
6. Common Language Runtime(CLR) 환경에서 위 Assembly파일의 IL코드들이 정상적인지 확인 절차를 밟은 뒤
함수가 호출되는 순간 '현재 프로그램이 돌아가는 컴퓨터 환경'에 적합한 기계 언어로 만들어낸다.
7. 그리고 이 함수가 다음 번에 호출이 될 때 바로 사용될 수 있게 위 기계 언어코드를 Cache(캐시)에 저장해둔다.
8. 위와 같은 기법을 JIT Compiling(Just In Time) 기법이라고한다. 여기서 중요한 것은 현재 컴퓨터에 적절한 기계 언어를 생성하는 것인데 이게 CLR의 강점이다.
※ Assembly가 실행되는 동안 CLR은 보안, 메모리 관리, 스레딩에 관련된 서비스를 제공하는데. 이러한 특징들은
해당 응용 프로그램이 관리되어지고 있다(Managed)라고 표현해주는 것이다.
[ 단점 ]
- Memory cannot be directly allocated.
- 메모리 직접 할당이 안된다.
- In managed code, low-level access to the CPU architecture cannot be obtained.
- Software Translation Layer(소프트웨어 변화 계층)이라는 중간 과정을 거치지 않고 하드웨어를 직접적으로 구동하는 CPU구조적인 코드가 불가능하다.
참고 2: https://www.developer.com/microsoft/c-sharp/managed-unmanaged-native-what-kind-of-code-is-this/
이렇게 찾아봤던 것은 Managed, UnManaged 'code'이다. 마이크로소프트 문서에 쓰여져있는 것은
UnManaged Resources인데 이것들이 무엇인지 또한 알아봤다.
여러 가지가 있는데 흐름은 위에 정리한 것과 비슷한 것 같다.
.NET libraries와 CLR 관리를 받고있지 않은 리소스들이 Unmanaged Resources라고한다. 예를 들면 MemoryStream, SQLConnection같은 클래스 및 P/Invoke 등을 얘기하는 것 같다.
아래 주소에서 적절한 Disposable 활용 방법을 설명해주고있다.
https://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface
IDisposable을 활용하려는 두 가지 목적이있다.
1. Unmanaged Resource를 제거하기 위해 (Must)
2. Managed Resoruces를 제거하기 위해 (Recommended)
▼ 기본 뼈대
https://docs.microsoft.com/ko-kr/dotnet/api/system.gc.suppressfinalize?view=net-6.0
위 문서를 보니 이해가 잘 되었다. 이제 저기 주석 쳐놓은 곳에 메서드만 구현해주면 될 것 같다.
나중에 개인 포폴에 시스템 짤 때 활용해봐야겠다.
=====================
(+ 22.03.09)
https://www.youtube.com/watch?v=CV5UlcfFls4
자료를 더 참고하다가 위 영상을 통해 더 깊이 이해가 되었다.
[요약]
1. 가비지 컬렉터가 메모리 관리를 해주는 Managed Environment ((ex) .Net FrameWork.. etc) 안에서 Resource를 다룰 때 솔직히 소멸[종료]자 (Finalizer)는 필요없다. Finalization을 활용해야할 때는 'UnManaged Resources'를 다룰 때 이다.
여기서 UnManaged에 대해서 확실해졌다. 아래 사진과 같이 외부에서 다운 받는 리소스들이 UnMangaed이다.
▼ 해당 자료를 다운 받아봤다.
==========
※ 다른 점
.Net Framework의 관리를 받고 있는 StreamWrtier은 Managed Resource 이고
외부에서 다운 받은 Microsoft.Office.Interop.Excel.dll에서 임포트하여 활용하는 모든 것들은 UnManaged이다.
2. 그래서 소멸자에서는 Dispose(false)를 통해 UnManaged 리소스를 Dispose해줘야한다. 왜냐하면 소멸자에 들어갔을 때 관리를 받고있는 StreamWriter는 이미 GC가 발생하고있기 때문이다.
-!! 만약에 소멸자에 StreamWriter.Dispose (= Dispose(true) )를 해준다면 Exception을 뱉어낼 것이다 !!-
3. 만약에 Dispose()를 임의로 실행해준다면 Dispose(true)로 Managed와 UnManaged리소스를 같이 Dispose해주는데
그런 경우에는 GC가 소멸자를 발생시키지 않도록 GC.SuppressFinalize(this)를 해주는 것이다.
4. 그래서 요약하면 Dispose 패턴은 UnManaged Resource를 사용할 때 필요한 패턴이다. 그러한 상황이 아니라면
굳이 시도하지마라. 성능 저하만 일으킨다.
== ▼ 최종
'개발 (언어) > C#' 카테고리의 다른 글
[C#] Get, Set 프로퍼티를 왜 사용할까? (0) | 2023.02.26 |
---|