AppDomain.Unload (myDomain)을 수행 할 때도 전체 가비지 수집을 수행 할 것으로 예상됩니다. 의 제프리 리히터에 따르면AppDomain.Unload를 호출해도 가비지 수집이 발생하지 않는 이유는 무엇입니까?
그가의 AppDomain.Unload 중에 있다고 말한다 "CLR C#을 통해"에 의해 생성 된 모든 객체 사용하는 메모리를 회수,
는 CLR이 발생하는 가비지 수집을 강제로 이제 언로드 된 AppDomain. 에 대한 Finalize 메서드가 호출되어 개체에서 올바르게 정리할 수 있습니다. "사용자 정의 .NET Framework 공용 언어 런타임"에서 "스티븐 Pratschner"에 따르면
: 모든 파이 나라 실행 한 더 이상 스레드가 도메인에서 실행되지 않습니다 후
는 CLR이 언로드 할 준비가 내부 구현에 사용 된 모든 메모리 내 데이터 구조 그러나 이렇게되기 전에 도메인에있는 개체를 수집해야합니다. 다음 가비지 수집이 발생하면 응용 프로그램 도메인 데이터 구조가 프로세스 주소 공간에서 언로드되고 도메인은 언로드 된 것으로 간주됩니다.
나는 그들의 말을 잘못 해석합니까? 나는 (.NET 2.0 SP2의) 예상치 못한 동작을 재현 할 수있는 다음과 같은 솔루션을했다 :
이 인터페이스를 포함하는 "인터페이스"라 불리는 클래스 라이브러리 프로젝트 :
public interface IXmlClass
{
void AllocateMemory(int size);
void Collect();
}
클래스 라이브러리 프로젝트라는 "으로 ClassLibrary1을" 이는 "인터페이스"를 참조하고이 클래스가 포함되어 다음과 같은 논리를 "인터페이스"프로젝트를 참조하고 수행
public class XmlClass : MarshalByRefObject, IXmlClass
{
private byte[] b;
public void AllocateMemory(int size)
{
this.b = new byte[size];
}
public void Collect()
{
Console.WriteLine("Call explicit GC.Collect() in " + AppDomain.CurrentDomain.FriendlyName + " Collect() method");
GC.Collect();
Console.WriteLine("Number of collections: Gen0:{0} Gen1:{1} Gen2:{2}", GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2));
}
~XmlClass()
{
Console.WriteLine("Finalizing in AppDomain {0}", AppDomain.CurrentDomain.FriendlyName);
}
}
콘솔 응용 프로그램 프로젝트 :
를 691,363,210static void Main(string[] args)
{
AssemblyName an = AssemblyName.GetAssemblyName("ClassLibrary1.dll");
AppDomain appDomain2 = AppDomain.CreateDomain("MyDomain", null, AppDomain.CurrentDomain.SetupInformation);
IXmlClass c1 = (IXmlClass)appDomain2.CreateInstanceAndUnwrap(an.FullName, "ClassLibrary1.XmlClass");
Console.WriteLine("Loaded Domain {0}", appDomain2.FriendlyName);
int tenmb = 1024 * 10000;
c1.AllocateMemory(tenmb);
Console.WriteLine("Number of collections: Gen0:{0} Gen1:{1} Gen2:{2}", GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2));
c1.Collect();
Console.WriteLine("Unloaded Domain{0}", appDomain2.FriendlyName);
AppDomain.Unload(appDomain2);
Console.WriteLine("Number of collections after unloading appdomain: Gen0:{0} Gen1:{1} Gen2:{2}", GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2));
Console.WriteLine("Perform explicit GC.Collect() in Default Domain");
GC.Collect();
Console.WriteLine("Number of collections: Gen0:{0} Gen1:{1} Gen2:{2}", GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2));
Console.ReadKey();
}
콘솔 응용 프로그램을 실행하는 출력은 다음과 같습니다
Loaded Domain MyDomain
Number of collections: Gen0:0 Gen1:0 Gen2:0
Call explicit GC.Collect() in MyDomain Collect() method
Number of collections: Gen0:1 Gen1:1 Gen2:1
Unloaded Domain MyDomain
Finalizing in AppDomain MyDomain
Number of collections after unloading appdomain: Gen0:1 Gen1:1 Gen2:1
Perform explicit GC.Collect() in Default Domain
Number of collections: Gen0:2 Gen1:2 Gen2:2
것들 통지 :
쓰레기 수집이 프로세스 당 이루어집니다 (다만 재교육)
객체 언로드 된 appdomain에서 finalizer가 호출되었지만 가비지 수집이 수행되지 않았습니다.) AllocateMemory (의해 만들어진 10 메가 목적은 (상기 실시 예에서 명시하는 GC.Collect()를 수행 한 후 수집되거나 가비지 수집기가 언젠가 나중에
기타 참고한다면 :. 그것이 케이 . 'XmlClass가 마무리가인지 아닌지 t 정말 문제는 같은 문제가 위의 예에서 발생
질문 :.
왜의 AppDomain.Unload는 가비지 콜렉션 발생하지 않습니다 부르심 않습니다를?해당 호출 결과를 가비지 수집으로 만들 수있는 방법이 있습니까?
Inside AllocateMemory() LargeObject 힙을 가져오고 생성 2 개체가 될 짧은 수명의 큰 xml 문서 (16MB 이하)를로드 할 계획입니다. 명시적인 GC.Collect() 또는 가비지 수집기의 명시 적 프로그래밍 방식 컨트롤의 다른 종류를 사용하지 않고 메모리를 수집 할 수있는 방법이 있습니까?
전적으로 동의합니다. – Steven
아마도 의도적으로 질문에 추가 된 내 노트를 참조하십시오. –