2013-09-30 3 views
2

특정 컴퓨터에서 OutOfMemoryExceptions을 사용하는 NUnit 테스트를 테스트했습니다.OutOfMemoryException 테스트를 실행할 때 특정 컴퓨터에서

조사한 결과 메모리 문제는 아니지만 핸들 문제 (우리는 너무 많은 비트 맵 객체를 할당하고 해제하지 않음)를 보였다.

이것은 특정 시스템에서 완벽하게 실행되지만 다른 시스템에서는이 오류로 인해 실패합니다.

  1. 기계입니다 실패는 Windows7의 64와 하이퍼 V VM (6 기가 바이트 램)
  2. 워킹 머신은 실제 머신의 Windows XP (2 기가 바이트 램)

내가 아는이 가장 좋은 방법은 어떤 Bitmap 객체를 처리하기 위해 코드를 정리하는 것이지만 동일한 코드를 실행할 때이 두 머신의 동작이 다른 이유는 무엇입니까?

+1

음, .NET 프레임 워크는 동일 할 수 있지만 기본 OS는 다를 수 있습니다. 비트 맵과 같은 리소스는 여전히 운영 체제에서 처리됩니다. Windows 7은 Windows XP와 다른 방식으로 리소스를 처리하므로 서로 다른 버전의 Windows에서 서로 다른 결과를 얻는 것은 놀라운 일이 아닙니다. – helb

+0

Windows가 더 이상 발급을 거부하기 전에 누출 될 수있는 핸들 수를 구성 할 수 있습니다. 기계 중 하나가 다르게 구성되었을 수도 있습니다. –

+0

감사합니다. 이것이 어디에서 제어 될 수 있는지 알고 있습니까? –

답변

1

이 읽기 ​​: http://blogs.technet.com/b/markrussinovich/archive/2010/02/24/3315174.aspx

당신은 GDI 힙에 대한 윈도우의 다양한 버전의 차이점에 테이블을 찾을 수 있습니다. 짧은 대답 : XP = 3MB 제한, Win7R2x64 = 20MB 제한. 무료 RAM은 중요하지 않으며, 이는 엄격한 제한 사항입니다.

+0

이것은 XP에서는 크래시가 발생하지 않고 Win7에서는 그렇지 않습니다. ( –

+1

당신의 조건이 지금과 반대되는 것을 맹세 할 수 있었습니까? – jlew

1

Windows에서는 프로그램 동작 방식이 까다롭게 나타나기 전에 10,000 개의 핸들이 누출 될 수 있으며 더 많은 할당을 거부합니다. 그때까지는 비트 맵의 ​​픽셀 데이터를 위해 엄청난 양의 가상 메모리 공간을 소비했습니다. 관리되지 않는 메모리에 저장된 가비지 컬렉터는이를 인식하지 못합니다. Dispose()를 호출하거나 가비지 수집기가 finalizer를 실행하여 처리하지 않으면 VM 공간이 해제됩니다.

일반적으로 GC가 작업을 완료하지는 않지만 Bitmap 클래스는 매우 작은 개체이며 GC 자체를 실행하기에 충분하지 않습니다. GC를 트리거하려면 약 60,000 개를 할당해야합니다. 당신은 결코 거기에 도착하지 않을 것이고, 비트 맵이 아주 작지 않고 VM 공간이 부족할 것입니다. Dispose()를 호출하는 것은 선택 사항이지만, 파이널 라이저는 시간 내에 작업을 완료 할 수 없으므로 비트 맵에 대해서는 선택 사항이 아닙니다.

RAM의 양은 아무런 역할을하지 않습니다. .NET 프로그램은 요청 된 크기에 맞게 충분히 큰 VM 주소 공간에서 구멍을 찾을 수 없기 때문에 항상 폭탄을 터뜨립니다. 또한 비트 맵 문제는 큰 구멍이 필요한 경향이 있습니다. 좋은 DLL을 두 개로 자르려면 어색한 기본 주소로로드되는 DLL 만 필요합니다. 그렇지 않으면 쉽게 해결할 수있는 문제가 있습니다. 프로그램의 대상 플랫폼을 AnyCPU로 설정하면됩니다. 테스트 프로그램에는이를위한 구성 값이 있습니다. 그 Win7 컴퓨터에서 작동합니다. 물론 Dispose() 호출을 건너 뛰는 유효한 이유는 아닙니다.

관련 문제