.Net에서 가비지 수집과 관련하여 몇 가지 흥미로운 동작이 나타났습니다..Net에서 가비지 수집을 트리거하는 기준
다음 프로그램은 매우 빨리 OutOfMemoryException을 throw합니다 (32 비트 2GB 시스템에서는 1 초 미만). Foo finalizer는 호출되지 않습니다. rand.nextBytes 라인이 주석 인 경우
class Foo
{
Guid guid = Guid.NewGuid();
byte[] buffer = new byte[1000000];
static Random rand = new Random();
public Foo()
{
// Uncomment the following line and the program will run forever.
// rand.NextBytes(buffer);
}
~Foo()
{
// This finalizer is never called unless the rand.NextBytes
// line in the constructor is uncommented.
}
static public void Main(string args[])
{
for (; ;)
{
new Foo();
}
}
}
, 그것은 광고 인해서 실행하고 푸 파이널 정기적으로 호출됩니다. 왜 그런가요?
가장 좋은 추측은 전자의 경우 CLR 또는 Windows VMM 중 하나가 실제 메모리를 할당하는 것을 게으른 것입니다. 버퍼는 결코 기록되지 않으므로 실제 메모리는 사용되지 않습니다. 주소 공간이 부족하면 시스템이 충돌합니다. 후자의 경우 시스템의 주소 공간이 부족해지기 전에 실제 메모리가 부족하여 GC가 실행되고 개체가 수집됩니다.
그러나 여기서는 내가 알지 못하는 부분이 있습니다. 내 이론이 맞다고 가정하면 주소 공간이 부족할 때 GC가 트리거하지 않는 이유는 무엇입니까? 내 이론이 틀렸다면, 진짜 설명은 뭐니?
I는 프로그래머가 그것을 잊어 버린 경우에도
Dispose()
를 호출 할 매우 중요한 것입니다 경우에만 종료자를 사용 네가 옳은 대답을하고 있는지 확신 할 수 없지만, 너는 나를 흥미로운 길로 가게했다. 나는 실행중인 두 개의 가상 PC (512MB)를 종료하고 나는 당신의 행동을 얻는다. VPC를 다시로드하면 원래의 충돌 동작이 발생합니다. –'GC' 클래스에서 몇 가지 흥미로운 기능들이 있지만, 실제 코드에서는 결코 사용해서는 안됩니다. –
VPC를 실행하고 Thread.Sleep (0)을 제자리에두면 프로그램이 영원히 실행됩니다. 이제 질문이 바뀝니다 ... GC가 할당 실패로 인해 자동으로 트리거되지 않는 이유는 무엇입니까? –