1

메모리 누수

메모리 누수

노아의 블로그

    목차
반응형

크롤링을 하려던 중, 메모리 누수에 관련해서 찾아보게 되었다.

z

오.. 뭔가 모르는것이 많이 보인다.

 

일단, 첫번째 줄 using을 살펴보도록 하자.

using 은 보통 namespace를 사용할 때 많이 사용했는데.... 이곳에도 많이 쓰인다.

 

하지만 설명하기 전에 먼저, GC와 Dispose라는것을 알아야 한다. 

 

1.GC는 가비지 컬렉터로, 메모리 관리를 해주는 유용한 놈이다. 자동으로 메모리 할당 해제를 해주어 개발자의 작업을 줄여준다.

 

하지만 문제가 있다. 바로 GC는 관리되지 않는 메모리를 할당하거나 해제하지 않다고 나와있다.

출처 : 마이크로소프트 2번째 문단

 

Dispose 메서드 구현 - .NET

이 문서에서는 .NET에서 코드에 사용되는 비관리형 리소스를 해제하는 Dispose 메서드를 구현하는 방법을 알아봅니다.

learn.microsoft.com

 

자 그렇다면 관리되지 않는 메모리가 도대체 뭘까??? 너무 추상적인 존재다.

 

출처 : 마이크로소프트

 

가비지 수집 기본 사항 - .NET

가비지 수집기의 작동 원리와 최적 성능으로 구성하는 방법에 대해 알아봅니다.

learn.microsoft.com

 

그렇다. 운영 체제 리소스를 래핑하는 개체가 바로 관리되지 않은 리소스라고 할 수 있다. 

그렇다면 관리되지 않은 리소스를 방치하면 결국 사용하지 않는 메모리가 계속 차지하게 될것이고,

그것은 결국 메모리 누수(Memory leak) 가 될것이다.

 

메모리 누수란, 사용하지 않는 메모리 공간을 계속 차지하고 있는것이다.

 

그렇다면 직접 한번 메모리 누수를 테스트 해 보자.

 

먼저 관리가 되는 리소스를 만들기 위해 일반 클래스를 하나 만든다.

그리고 객체를 반복해서 100번 생성한다. 하지만 관리되는 리소스에 해당한다면 GC가 반복문을 돌때마다 삭제하고 다시 생성해서 이론상 누적되지 않을것이다..

 

그렇다면 이렇게 하면 메모리 누수가 발생할것이라고 예상했다. 

물론 누수가 발생한것이 맞긴하지만 내가 생각한 것과 약간 다르다.

 

나는 인스턴스 자체가 관리가 안된다고 받아들였는데, 메모리 스냅샷을 진행한 결과 인스턴스는 가비지 컬렉터에 의해 관리가 되고 있었다.... 

그렇다면 이제 폴더에 가보자.

타깃 폴더에 파일이 생성되어있는것을 볼 수 있다.

프로세스를 종료하지 않은 상태에서 이렇게 100개 생성된 파일을 한번 지워보자.

파일이 열려있다고 나오면서 파일을 삭제하지 못한다.

 

인스턴스는 정리가 되었지만, 뭔가가 계속 유지중이라는것을 알 수 있다. 

음...지금은 일단 구체적으로 무엇인지는 모르겠지만 운영체제의 리소스에 관련된 것이 열려있다는것은 확실하다.

 

 

이제 프로세스를 종료해본다. 프로세스를 종료하니 파일을 지울 수 있게 되었다.

출처 : 마이크소로프트

 

Windows 애플리케이션에서 메모리 누수 방지 - Win32 apps

Windows 7 및 Windows Server 2008 R2 플랫폼용 Windows 애플리케이션에서 메모리 누수를 방지하는 방법을 알아봅니다.

learn.microsoft.com

이 또한 이곳에서 알 수 있었다.

내용에 따르면 OS에서 프로세스 종료에 할당한 모든 메모리를 해제한다!! 

 

프로그램이 종료되면 메모리를 해제하니 괜찮을까? 라는 생각이 들 수 있어도,

지금 만든 테스트 케이스는 단지 100번 반복하고 종료하는 간단한 것이라서 별로 큰 효과가 없는 것이다.

프로그램의 규모가 커지고 계속 실행이 되는 상태라면 메모리의 공간이 중요할 것이다.

이렇게 계속 100번...1000번씩 쌓이면 나중에는 쓰레기로 가득찬 메모리가 될것!!

 

이렇게 많은 여정을 거쳐서 결국 메모리를 해제해야한다는 결론이 생긴다.

 

자 그럼 이제 이 관리되지 않는 리소스는 결국 수동으로 할당 해제를 해야한다는 말이다.

여기서 이제 Dispose라는것이 나온다.

 

관리되지 않는 개체는 IDisposable이라는 인터페이스를 상속받아 명시적 해제를 구현하고 있다.

 

그래서, 파일 스트림에 dispose를 호출하면 리소스 해제가 가능하다. 또는 Close라는 메서드도 이용이 가능하다.

 

이렇게 해제를 해도 가능하지만, using문을 사용해서 더욱 효과적으로 개발을 할 수 있다.

이런식으로 c#에서 using을 사용해서 괄호 블록까지만 이놈이 살아있도록 만들 수 있다! (괄호 나오면 리소스 해제됨)

반응형