CLI Native objects getting stuck in gen2 and not garbage collected

妖精的绣舞 提交于 2019-12-13 07:15:03

问题


I am working on this high frequency production system. There is a C# / CLI layer which calls into a C++ library. What we are observing is that managed objects are going into generation 2 of the garabage collector and getting 'stuck'. Eventually the C# applications grind to a halt as RAM runs out. These managed objects are local objects and should have a very short lifetime. Also they are only referenced once. The C# applications are having to call .Dispose() on all their objects that hold native resources to ensure everything is forcefully deleted. We have quite a few objects so this isn't ideal and from an API perspective is messy. The CLI looks like this:

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

Can anyone think why these short lived objects never seem to be collected and free the memory?


回答1:


The problem is unmanaged objects don't count toward the "memory pressure" value that the GC uses to decide when to do a garbage collection.

One thing you can do is use GC.AddMemoryPressure( to let the GC know that there is a large unmanaged object associated with your managed wrapper.

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


来源:https://stackoverflow.com/questions/40111289/cli-native-objects-getting-stuck-in-gen2-and-not-garbage-collected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!