簡體   English   中英

CLI本機對象卡在gen2中且未進行垃圾收集

[英]CLI Native objects getting stuck in gen2 and not garbage collected

我正在這個高頻生產系統上工作。 有一個C#/ CLI層,它調用C ++庫。 我們正在觀察的是,托管對象正在進入垃圾收集器的第二代,並被“卡住”。 最終,隨着RAM耗盡,C#應用程序陷入停頓。 這些托管對象是本地對象,應具有非常短的生命周期。 同樣,它們僅被引用一次。 C#應用程序必須在擁有本地資源的所有對象上調用.Dispose(),以確保強制刪除所有內容。 我們有很多對象,所以這不是理想的,並且從API的角度來看很雜亂。 CLI看起來像這樣:

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;
    }
}

誰能想到為什么這些短暫存在的對象似乎從未被收集過並釋放了內存?

問題是非托管對象沒有計入GC用來決定何時進行垃圾收集的“內存壓力”值。

您可以做的一件事是使用GC.AddMemoryPressure(讓GC知道有一個與托管包裝相關聯的大型非托管對象。

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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM