관리되지 않는 리소스 란 정확히 무엇입니까?


답변:


177

관리 자원은 기본적으로 가비지 콜렉터가 관리하는 "관리 메모리"를 의미합니다. 더 이상 관리 대상 메모리를 사용하는 관리 대상 객체에 대한 참조가 없으면 가비지 콜렉터가 결국 해당 메모리를 해제합니다.

관리되지 않는 리소스는 가비지 수집기에서 알 수없는 모든 것입니다. 예를 들면 다음과 같습니다.

  • 파일 열기
  • 개방형 네트워크 연결
  • 관리되지 않는 메모리
  • XNA에서 : 정점 버퍼, 인덱스 버퍼, 텍스처 등

일반적으로 관리 대상 자원 에 대한 모든 참조를 잃기 전에 관리되지 않는 자원을 해제하려고 합니다. Dispose해당 개체 를 호출 하거나 C #에서 using호출 Dispose을 처리하는 문을 사용 하여이 작업을 수행 합니다.

Dispose관리되지 않는 리소스를 올바르게 무시하면 해당 리소스가 포함 된 객체가 가비지 수집 될 때 가비지 수집기에서 리소스를 처리합니다 ( "최종화"). 그러나 가비지 수집기는 관리되지 않는 리소스에 대해 알지 못하기 때문에 리소스를 얼마나 많이 해제해야하는지 알 수 없으므로 프로그램의 성능이 저하되거나 리소스가 부족할 수 있습니다.

당신이 핸들 자원을 관리되지 않는하는 클래스를 직접 구현하는 경우, 그것을 구현하는 당신에게 달려 DisposeFinalize올바르게.


7
오픈 데이터베이스 연결은 어떤 범주에 속합니까? 관리 / 관리되지 않습니까?
Deviprasad Das

8
+1 다른 답변은 관리 대상 개체에서 랩핑 된 관리되지 않는 리소스의 해제 (예 : 파일 핸들, GDI + 비트 맵 등)를 처리하고 관리되지 않는 리소스에 직접 액세스하면 ( PInvoke 등) 처리해야합니다.
이안 머서

2
@Dev : 관리되지 않음-GC가 알지 못하기 때문에 (가정적인 메모리 관리 데이터베이스를 사용하지 않는다고 가정). 그러나 연결 개체 자체 에는 관리되지 않는 리소스가 없을 수 있습니다. 아마도 데이터베이스 연결이 열린 파일 또는 네트워크 연결을 사용하는 곳을 -하지만 가능한 다른 개체 (연결 개체가 아닌)이 처리되어 그 관리되지 않는 자원 (아마도 데이터베이스 라이브러리 캐시 연결). 설명서를 확인하고 전화 Dispose또는 사용 을 요청하는 곳을 확인하십시오 using.
Andrew Russell

11
이것에 대한 기본 의견 / 질문이 있습니다. 예를 들어 문자열이 관리되고 DataSet이 관리되지 않는 것 (예 : Dispose () 메서드가있는)과 같이 유형에 따라 관리되거나 관리되지 않는 객체를 관련시킬 수 있습니다 , 데이터베이스 연결은 관리되지 않기 때문에 (처분 되었기 때문에), "Dispose ()"메소드가 있다고 가정하면 관리되지 않습니까? 그 외에도 XmlDocument 객체는 무엇입니까? 감사합니다
ganders

15
@ganders 그것은 좋은 경험 법칙입니다. 모든 C # 클래스 인스턴스는 관리되는 개체라는 점에 유의하십시오. 클래스의 인스턴스가 관리되지 않는 리소스를 보유 할 수 있으면 해당 클래스 는를 구현 해야 합니다 IDisposable. 클래스가되면 않는 구현 IDisposable, 당신은 해야 와 그 클래스의 인스턴스 처분 using또는 Dispose()당신이 그들과 함께 할 때. 이를 바탕으로하여 반대의 보유 : 클래스가 구현되면 IDisposable, 그때는 아마 내부적으로 관리되지 않는 리소스를 보유하고 있습니다.
Andrew Russell

56

일부 사용자는 열린 파일, DB 연결, 할당 된 메모리, 비트 맵, 파일 스트림 등을 관리되는 리소스 중에서 순위를 매기고 다른 사용자는 관리되지 않는 리소스 중에서 순위를 매 깁니다. 그래서 그들은 관리되거나 관리되지 않습니까?

내 의견은 응답이 더 복잡하다는 것입니다. .NET에서 파일을 열 때 내장 .NET 클래스 System.IO.File, FileStream 또는 다른 것을 사용할 수 있습니다. 일반적인 .NET 클래스이므로 관리됩니다. 그러나 실제로는 파일을 여는 "더러운 작업"(Win32 dll을 사용하여 운영 체제와 통신하거나 하위 수준 함수를 호출하거나 어셈블러 명령을 수행)과 같은 래퍼입니다. 그리고 이것은 .NET이 알지 못하는 관리되지 않는 것입니다. 그러나 어셈블러 지침을 사용하고 .NET 파일 기능을 무시하고 파일을 직접 열 수 있습니다. 그런 다음 핸들과 열린 파일은 관리되지 않는 리소스입니다.

DB와 동일 : 일부 DB 어셈블리를 사용하는 경우 DbConnection 등과 같은 클래스가 있으며 .NET에 알려지고 관리됩니다. 그러나 관리되지 않는 "더러운 작업"을 래핑합니다 (서버의 메모리 할당, 연결 설정 등). 이 랩퍼 클래스를 사용하지 않고 직접 네트워크 소켓을 열고 일부 명령을 사용하여 이상한 데이터베이스와 통신하는 경우 관리되지 않습니다.

이러한 래퍼 클래스 (File, DbConnection 등)는 관리되지만 래퍼를 사용하지 않고 직접 "더러운 작업"을 수행하는 경우 내부와 동일한 방식으로 관리되지 않는 리소스를 사용합니다. 따라서 이러한 래퍼는 Dispose / Finalize 패턴을 구현합니다. 랩퍼가 더 이상 필요하지 않은 경우 프로그래머가 관리되지 않는 자원을 해제하고 랩퍼가 가비지 수집 될 때 해제하는 것은 그들의 책임입니다. 래퍼는 가비지 수집기에서 올바르게 가비지 수집하지만 내부의 관리되지 않는 리소스는 Dispose / Finalize 패턴을 사용하여 수집됩니다.

내장 .NET 또는 타사 래퍼 클래스를 사용하지 않고 클래스에서 어셈블러 명령 등으로 파일을 열면 이러한 열린 파일이 관리되지 않으므로 처리 / 완료 패턴을 구현해야합니다. 사용하지 않으면 더 이상 사용하지 않거나 (파일 작업이 완료된 경우) 또는 응용 프로그램이 종료 된 후에도 메모리 누수, 리소스 잠김 등이 발생합니다.

그러나 이러한 랩퍼를 사용할 때는 사용자의 책임도 있습니다. 처리 / 완료를 구현하는 사용자 (이를 인식하고 IDisposable을 구현 함)의 경우 처리 / 완료 패턴도 구현하고 이러한 래퍼도 처리하거나 관리되지 않는 리소스를 해제하라는 신호를 보냅니다. 그렇지 않은 경우 리소스가 무기한 해제 된 후 자원이 해제되지만 즉시 해제 할 수 있습니다 (파일을 즉시 닫고 열어 두지 않고 무작위로 몇 분 / 시간 동안 차단하지 마십시오). 따라서 클래스의 Dispose 메서드에서 사용 된 모든 래퍼의 Dispose 메서드를 호출합니다.


1
추가 명확성에 대한 좋은 점unmanaged vs managed resources
이제 이름을 지어야하는 사람.

당신의 대답을 위해 thx. 실제로 Dispose를 호출하는 것이 권장되는 클래스는 무엇입니까?
BKSpurgeon

2
이것은 간단합니다. 사용하는 각 클래스에서 IDisposable 인터페이스를 구현하는지 여부를 확인해야합니다. 그렇다면, 클래스를 하나의 메소드 (예 : 파일 열기, 텍스트 저장, 파일 닫기)에서 사용하는 경우 자동으로 Dispose를 호출하는 using () {} 패턴을 사용할 수 있습니다. 더 많은 메소드에서 이러한 클래스를 사용하는 경우 (예 : 클래스에 File이 포함되어 있고 생성자에 파일이 열리고 여러 메소드가 일부 로그를 추가하는 경우) 클래스에 의해 IDisposable 인터페이스를 구현하고 Dispose / Finalize 패턴을 구현해야합니다 해당 클래스의 객체를 올바르게 처리하십시오.
Martas

1
"... 일부 내장 .NET 클래스 System.IO.File, FileStream 또는 기타. 일반적인 .NET 클래스이기 때문에 관리됩니다." 이와 관련하여 이것은 잘못된 것이며 잘못된 것입니다. 그들은 관리되지 않습니다 . 이들이 관리되면 이러한 클래스를 할당하고 가비지 콜렉터가 모든 자원의 할당 해제를 결정적인 방식으로 완전히 처리 할 것으로 기대할 수 있습니다. 그러나 이로 인해 가비지 수집기가 클래스 할당을 해제하지 않고 잠재적으로 매우 오랫동안 종료하지 않기 때문에 파일 핸들과 관리되지 않는 리소스가 필요 이상으로 잠기고 유지됩니다.
AaronLS

1
@AaronLS는 귀하의 의견에 따르면 관리되지 않는 리소스를 사용하여 작업을 수행하지만 내부적으로 관리되지 않는 리소스를 사용하지만 "FileStream"에 대해서는 언급하지 않은 "FileStream"에 대해 이야기했습니다. 패턴을 폐기하십시오. 관리 코드는 관리되지 않는 리소스를 사용하지 않는다는 의미는 아닙니다. 그러나 Microsoft는 이러한 유형의 개체에 IDisposable을 구현하는 데 많은 노력을 기울였습니다. 이것은 IDisposable을 구현한다는 사실에 의해 입증됩니다. 그 증거와 관련하여 우리는 그것을 관리 대상으로 간주해야합니다.
Malik Khalil

12

관리되지 않는 리소스는 .NET 런타임 (CLR) 외부 (일명 비 .NET 코드) 외부에서 실행되는 리소스입니다. 예를 들어 Win32 API의 DLL 호출 또는 C ++로 작성된 .dll 호출입니다.


6

"관리되지 않는 리소스"는 문제가 아니라 책임입니다. 개체가 관리되지 않는 리소스를 소유 한 경우 (1) 정리되지 않은 경우 문제를 일으킬 수있는 방식으로 개체 외부의 일부 개체가 조작되었으며, (2) 개체는 이러한 정리를 수행하는 데 필요한 정보를 가지고 있으며 책임이 있음을 의미합니다. 해줘서

많은 유형의 관리되지 않는 리소스는 다양한 유형의 운영 체제 엔터티 (파일, GDI 핸들, 할당 된 메모리 블록 등)와 매우 밀접하게 관련되어 있지만 단일 책임 유형 이외의 다른 유형의 엔터티는 없습니다. 대청소. 일반적으로 개체가 정리를 수행해야 할 책임이있는 경우 Dispose 메서드를 사용하여 해당 개체를 담당하는 모든 정리를 수행하도록 지시합니다.

경우에 따라 객체는 먼저 Dispose를 호출 한 사람이 없어도 버릴 수있는 가능성을 허용합니다. GC를 사용하면 객체가 종료 된 루틴 (Finalize라는 루틴을 호출하여)에 대한 알림을 요청할 수 있으며, 객체는이 알림을 사용하여 정리를 수행 할 수 있습니다.

"관리 자원"및 "관리되지 않는 자원"과 같은 용어는 불행히도 다른 사람들이 다른 것을 의미하기 위해 사용합니다. 솔직히 정리할 책임이 없거나 Dispose가 호출 된 경우에만 처리 ​​할 정리 책임이 있거나 Dispose를 통해 처리해야하는 정리 책임이 있다고 생각하는 것이 개체 측면에서 더 유용하다고 생각하지만 또한 Finalize에 의해 처리됩니다.


5

관리 자원과 관리되지 않는 자원의 기본 차이점은 가비지 수집기가 모든 관리 자원에 대해 알고 있다는 점입니다. GC가 특정 시점에 관리 대상 객체와 관련된 모든 메모리와 자원을 정리합니다. GC는 파일, 스트림 및 핸들과 같은 관리되지 않는 리소스에 대해 알지 못하므로 코드에서 명시 적으로 정리하지 않으면 메모리 누수가 발생하고 리소스가 잠 깁니다.

여기 에서 도난당한 경우 전체 게시물을 자유롭게 읽으십시오.


2

.NET 관리되는 힙에 메모리가 할당 된 모든 리소스는 관리되는 리소스입니다. CLR은 이러한 종류의 메모리를 완전히 인식하고 있으며 고아가되지 않도록 모든 작업을 수행합니다. 다른 것은 관리되지 않습니다. 예를 들어 COM과의 상호 운용은 프로세스 메모리 공간에 객체를 만들 수 있지만 CLR은이를 처리하지 않습니다. 이 경우 관리되는 경계를 통해 호출하는 관리되는 개체는 그 밖의 모든 것에 대한 책임을 가져야합니다.


0

먼저 VB6 또는 C ++ 프로그램 (Non Dotnet 응용 프로그램)이 어떻게 실행되었는지 이해하겠습니다. 우리는 컴퓨터가 기계 수준 코드 만 이해한다는 것을 알고 있습니다. 기계 수준 코드는 기본 또는 이진 코드라고도합니다. 따라서 VB6 또는 C ++ 프로그램을 실행할 때 해당 언어 컴파일러는 해당 언어 소스 코드를 기본 코드로 컴파일 한 다음 기본 운영 체제 및 하드웨어에서 이해할 수 있습니다.

기본 코드 (관리되지 않는 코드)는 생성 된 운영 체제에 따라 다릅니다 (기본). 이 컴파일 된 네이티브 코드를 가져 와서 다른 운영 체제에서 실행하려고하면 실패합니다. 따라서이 스타일의 프로그램 실행의 문제점은 한 플랫폼에서 다른 플랫폼으로 이식 할 수 없다는 것입니다.

이제 .Net 프로그램이 어떻게 실행되는지 이해하겠습니다. 닷넷을 사용하여 다양한 유형의 응용 프로그램을 만들 수 있습니다. 일반적인 .NET 응용 프로그램 유형에는 웹, Windows, 콘솔 및 모바일 응용 프로그램이 있습니다. 응용 프로그램 유형에 관계없이 .NET 응용 프로그램을 실행할 때 다음이 발생합니다.

  1. .NET 애플리케이션은 IL (Intermediate Language)로 컴파일됩니다. IL은 CIL (Common Intermediate language) 및 MSIL (Microsoft Intermediate language)이라고도합니다. .NET 및 비 .NET 응용 프로그램 모두 어셈블리를 생성합니다. 어셈블리의 확장명은 .DLL 또는 .EXE입니다. 예를 들어 Windows 또는 콘솔 응용 프로그램을 컴파일하면 .EXE가 발생하며 웹 또는 클래스 라이브러리 프로젝트를 컴파일 할 때 .DLL이 생성됩니다. .NET과 NON .NET 어셈블리의 차이점은 DOTNET 어셈블리는 NON DOTNET 어셈블리가 기본 코드 형식 인 중간 언어 형식이라는 것입니다.

  2. NOT DOTNET 응용 프로그램은 운영 체제에서 직접 실행될 수 있으며 DOTNET 응용 프로그램은 CLR (Common Language Runtime)이라는 가상 환경에서 실행됩니다. CLR에는 JIT (Just In-Time Compiler)라는 구성 요소가 포함되어 있습니다.이 구성 요소는 중간 언어를 기본 운영 체제가 이해할 수있는 기본 코드로 변환합니다.

따라서 .NET에서 응용 프로그램 실행은 2 단계로 구성됩니다. 1. 언어 컴파일러, 소스 코드를 IL (Intermediate Language)로 컴파일합니다. 2. CLR의 JIT 컴파일러는 IL을 기본 코드로 변환 한 다음 기본 운영 체제에서 실행할 수 있습니다. .

.NET 어셈블리는 기본 코드가 아닌 Intermedaite 언어 형식이므로 .NET 어셈블리는 대상 플랫폼에 CLR (공용 언어 런타임)이있는 한 모든 플랫폼에 이식 가능합니다. 대상 플랫폼의 CLR은 Intermedaite 언어를 기본 운영 체제가 이해할 수있는 기본 코드로 변환합니다. 중급 Languge는 관리 코드라고도합니다. CLR이 내부에서 실행되는 코드를 관리하기 때문입니다. 예를 들어, VB6 프로그램에서 개발자는 객체가 사용하는 메모리를 할당 해제해야합니다. 프로그래머가 메모리 할당 해제를 잊어 버리면 메모리 예외를 감지하기가 어려울 수 있습니다. 반면에 .NET 프로그래머는 객체가 소비하는 메모리를 할당 해제하는 것에 대해 걱정할 필요가 없습니다. CLR은 grabage collection이라고도하는 자동 메모리 관리 기능을 제공합니다. 떨어져서, 가비지 수집에서 CLR이 제공하는 몇 가지 다른 이점이 있습니다. CLR은 중간 언어를 관리하고 실행하기 때문에 관리 코드라고도합니다.

.NET은 C #, VB, J # 및 C ++와 같은 다른 프로그래밍 언어를 지원합니다. C #, VB 및 J #은 관리 코드 (IL) 만 생성 할 수 있습니다. 여기서 C ++은 관리 코드 (IL)와 비 관리 코드 (네이티브 코드)를 모두 생성 할 수 있습니다.

네이티브 코드는 프로그램을 닫은 후에는 영구적으로 저장되지 않으며 네이티브 코드는 버려집니다. 프로그램을 다시 실행하면 원시 코드가 다시 생성됩니다.

.NET 프로그램은 Java 프로그램 실행과 유사합니다. 자바에는 바이트 코드와 JVM (Java Virtual Machine)이 있으며 .NET에서와 같이 중간 언어 및 CLR (Common Language Runtime)

이것은이 링크에서 제공됩니다-그는 훌륭한 교사입니다. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.