2010-12-07 1 views
1

COM interop을 통해 Visual Basic .NET 응용 프로그램에서 사용하고있는 VB6로 작성된 COM 구성 요소가 있습니다.내 COM 구성 요소가 OutOfMemoryException을 throw하지만 VB6에서 제대로 실행되는 이유는 무엇입니까?

VB.NET에서 호출 할 때 OutOfMemoryException을 throw하는 메서드가 있습니다. 그러나 Visual Basic 6 응용 프로그램에서 똑같은 호출을 실행하면 모든 것이 잘 동작합니다.

VB6에서 디버깅하려고하면 오류가 발생하지 않기 때문에 너무 길고 따라하기 힘듭니다 (코드 수정 문제가 있음) 및 문제를 찾아 낼 수 없어 코드를 여기 게시 할 수 없습니다. 보여줘.

이 별개의 동작을 유발할 수있는 원인은 무엇입니까?

Dictionary 개체 (Microsoft Scripting Runtime의 COM)를 사용하여 성능 문제를 해결할 때까지 문제가 없었습니다. 사전이 비합리적으로 성장하거나 누출되지 않는 한, 예외가 발생하기 전에 사전이 100-200 요소를 초과하지 않고 하나만 생성되기 때문에 이것이 사전에 원인이 될 수있는 방법을 알지 못합니다.

나는 Collection 개체와 어색한 Exists() 함수를 사용하여 동일한 문제를 해결했지만 동일한 문제가 발생합니다. Nothing을 반환하여 일찍 탈출하면 작동합니다 (즉, NullReferenceException이 throw됩니다).

+0

의미있는 스택 트레이스가 있습니까? 그리고 기억은 어떨까요? 프로세스의 크기는 얼마입니까? –

+0

@Simon : stacktrace는 COM/.NET 경계에서 끝납니다. 예외가 스택을 가로 질러 날아갈 때 프로세스는 약 100 megs입니다. –

+0

Scripting.Dictionary COM 개체는 STA (Apartment)로 표시되어 있습니다. 아래에서 weloytty가 설명했듯이 스레딩을 확인 했습니까? 그리고 BTW, 다중 스레드를 사용하여이 사전에 액세스하고 있습니까? –

답변

1

VB.NET의 메모리 관리는 매우 다릅니다. VB6에서는 COM 개체를 해제하기 위해 참조 계산을 사용하고 VB.NET에서는 가비지 수집기를 사용합니다. 특히 GC가 COM 개체를 해제 할 수있을만큼 자주 실행되지 않는 구성 요소를 단위 테스트 할 때 상황이 발생할 수 있습니다. 이러한 객체는 관리되지 않는 메모리를 할당하므로 컬렉션을 시작하기 위해 가비지 수집기에 압력을 가하지 않습니다.

성능 모니터 인 Perfmon.exe로 진단을 시작하십시오. 그래프를 마우스 오른쪽 단추로 클릭하고 카운터 추가를 클릭하고 .NET CLR 메모리, # Gen 0 컬렉션을 선택하고 프로세스를 선택합니다. 합리적인 속도로 카운터가 적어도 1 초마다 증가하는지 확인하십시오.

이러한 문제를 해결하는 것은 상당히 불쾌한 일이므로 구성 요소를 격리하여 인공적인 문제가 아닌지 확인하십시오. 또는 COM 객체에 대한 참조를 유지하면서 코드의 일반적인 버그. GC.Collect()와 GC.WaitForPendingFinalizers()를 호출하면 COM 개체가 해제됩니다. Marshal.ReleaseComObject()를 호출합니다. GC.AddMemoryPressure()를 사용하는 것도 가능한 해결 방법이지만, COM 개체에 필요한 관리되지 않는 메모리의 양을 합리적으로 생각해야합니다.

+0

코드의 .NET 부분을 건드리지 않았으므로 COM 객체에 대한 참조 유지로 인한 버그가 발생하지 않을 수 있습니다. perfmon을 사용하여 나는 실행 중에 매우 적은 수의 콜렉션을 보았습니다 : 던지기 전에 gen 2 콜렉션은 10 개 밖에 없었습니다. 현재로서는 성능 수정 사항을 .NET 레이어로 푸시하여 문제를 해결했습니다 ... –

관련 문제