[ .Net ] 할당과 제거 (unsafe, IDisposable, using,GC ...)

Lutica_·2025년 11월 15일

할당 (Allocation)

  • 할당이라 함은, 메모리저장할 장소를 확보하는 행위를 의미한다.

제거(소멸:Destruction)

  • 제거/소멸은 메모리에서 그 저장공간을 해제하고, 그 영역을 다시 운영체제에 반납하는 행위를 의미한다.

.Net의 Heap, Stack 할당.

Class - Allocation on Heap

  • Heap영역에서 Managed되는 Type에 해당한다.
  • 더이상 참조하지 않는 객체인 경우, 특수한 주기마다 동작하는 GC에 의하여 자동으로 반환된다.

Struct - Allocation on Stack

  • Unmanaged Type.
  • GC에 의해 수명피드백이 관리되지 않아 삭제되지 않고, 값처럼 취급되는 type이다.

using, IDisposable - 자동 해제를 위한 솔루션

유사한 사례로는, Kotlin/JVM의 use,AutoCloseable,Closeable,close가 있다.

IDisposable

  • IDisposable은 .Net에 정의된 표준 인터페이스중 하나이다.
  • 관리되지 않는 리소스를 해제하는 메커니즘을 제공합니다.라고 설명되어있는데, 이는 GC에 의해서 자동으로 정리되지 않는 리소스를 해제하여 Freezing현상을 막고, 제때제때 정리하는 변수임을 나타낸다.

void public Dispose()

  • 명세는 void public Dispose()를 구현할 것을 요구하고 있다.
  • 이는 특정 구문으로 Dispose()를 호출해 메모리를 해제하겠다는 일련의 약속으로, 특수한 메모리 해제를 요구하는 경우 이 함수를 호출해 메모리를 해제한다.

using

  • using구문은 두 가지 사용처가 있다.

F# open = C# using = import

using |static| <name_space>
using System
  • 간단하게, namespace등을 import하는 구문이다.
  • 이 구문을 쓰면 축약이 가능해진다는 장점이 있다.

F# use = C# using = use {} - RAII

using(var s = ...) {}
  • RAII(Resource acquisition is initialization) 라는 개념을 언어로 실질화 한 것으로, 자원의 획득과 소멸을 동시에 다루는 것을 의미한다.

예제

using System;
					
public class Program
{
	
	public class KindOfClass{
		// Heap할당이 일어나는 Class, 전역변수이므로 GC가 아닌 이상 사라지지 않는다.
		// 그런데. event가 덕지덕지 붙어있다고 가정하자.
		public event Action publishingDo;
		public void doing(){
			publishingDo?.Invoke();
		}
	}
	public class Somting : IDisposable { // 해제가능한 Class이다.
		KindOfClass kind = null;
		Action vas;
		public Somting(KindOfClass kd){
			kind = kd;
			this.vas = new Action(()=>{Console.WriteLine("HI!");});
			kd.publishingDo += this.vas;
		}
		public void Dispose(){
			if(kind != null) {
				kind.publishingDo -= vas;
			}
		}
	} 
		public static void Main()
		{
			var evch = new KindOfClass();
			using(var s = new Somting(evch)){
				evch.doing();
			}
			Console.WriteLine("Disposed!");
			evch.doing();

		}
}

unsafe

이때부터는 메모리관리를 깊게 나가는 부분이다.
OOP가 아니라 C를 먼저 해보고 보는걸 권장한다.

Span<T>

stackalloc

  • 강제로 스택에 할당하는 연산구문이다.
  • heap에 할당해야 할 부분을 Stack에 할당함으로서, 자동할당-해제의 이점을 누리겠다는 것이 이 요소의 특징이지만, 왠만해서는 나는 본 적이 없고 아마 볼 일도 없을 것 같다.
  • (차라리 쓸 바에는 Rust/C 이런거 쓰겠다.)
profile
해보고 싶고, 하고 싶은 걸 하는 사람

0개의 댓글