2016-10-18 12 views
0

이 고주파수 생산 시스템에서 작업 중입니다. C++ 라이브러리를 호출하는 C#/CLI 계층이 있습니다. 우리가 관찰하고있는 것은 관리 대상이 가라지 수집가의 2 세대로 들어가서 '붙어 다니기'라는 것입니다. 결국 RAM이 다 떨어지면서 C# 응용 프로그램이 중단됩니다. 이러한 관리 객체는 로컬 객체이므로 수명이 매우 짧아야합니다. 또한 그들은 한 번만 참조됩니다. C# 응용 프로그램은 모든 리소스가 강제로 삭제되도록 기본 리소스를 보유한 모든 개체에서 .Dispose()를 호출해야합니다. 우리에게는 꽤 많은 객체가 있으므로 이상적인 것은 아니며 API 관점에서 볼 때 지저분합니다. CLI는 다음과 같습니다 :CLI gen2에서 멈추고 가비지 수집되지 않는 원시 객체

Field::~Field() 
{ 
    if(m_pField != NULL) 
    { 
     delete m_pField; 
     m_pField = NULL; 
    } 
    System::GC::SuppressFinalize(this); 
} 

Field::!Field() 
{ 
    if(m_pField != NULL) 
    { 
     delete m_pField; 
    } 
} 

이 짧은 수명의 오브젝트가 수집되지 않고 메모리가 해제 된 것처럼 보이는 이유는 누구나 생각할 수 있습니까?

+0

. 올바른 용어를 사용하면 문제에 대한 해결책을 찾을 때 정보를 찾기가 어려울 수 있습니다. –

+0

임시 개체가 gen # 2로 승격 될 수있는 실용적인 시나리오는 많지 않습니다. 수정 구슬이 파이널 라이저 스레드가 교착 상태가되었다고합니다. 관리되지 않는 디버거를 사용해보십시오. –

+0

소급하여 이러한 일이 1 세대로 진행되었으며 우리가 한 분석이 잘못되었습니다. 스코 츠 추론이 이치에 맞습니다. – UltimateDRT

답변

3

관리되지 않는 개체는 GC가 가비지 수집을 수행 할시기를 결정하는 데 사용하는 "메모리 부족"값에 포함되지 않습니다.

당신이 할 수있는 한 가지는 GC.AddMemoryPressure(을 사용하여 관리되는 래퍼와 관련된 큰 관리되지 않는 개체가 있음을 GC에 알리는 것입니다.

그것은 [`C++/CLI` (https://en.wikipedia.org/wiki/C%2B%2B/CLI)하지 'C 번호/CLI`라고
Field::Field() 
{ 
    //... Other stuff 

    if(m_pField != NULL) 
    { 
     m_lSizeOfField = GetSizeOfField(m_pField); 
     System::GC::AddMemoryPressure(m_lSizeOfField); 
    } 
} 


Field::~Field() 
{ 
    //If you had managed objects you would call "delete" here on them. 
    //delete m_managedData; 

    //In C++/CLI if you have unmanged resources just have the dispose method 
    // call the finalizer. It is cleaner and easier to maintain. 
    // You can't do this in C# 
    this->!Field(); 

    //No need to add this next line, C++/CLI does it for you. 
    //System::GC::SuppressFinalize(this); 
} 

Field::!Field() 
{ 
    if(m_pField != NULL) 
    { 
     delete m_pField; 
     m_pField = NULL; 
     System::GC::RemoveMemoryPressure(m_lSizeOfField); 
    } 
} 
+0

다른 대안이 있습니까? 우리 고유의 객체의 크기를 찾는 일은 매우 까다 롭고 정확한 과학이 아닙니다. – UltimateDRT