1

我一直在从事的一个大型项目中遇到内存泄漏问题,但根据 VS2010 内存检查器,该项目没有泄漏(我已经广泛检查了所有内容)。

我决定编写一个简单的测试程序,看看泄漏是否会在较小的范围内发生。

struct TestStruct
{
    std::string x[100];
};
class TestClass
{
public:
std::vector<TestStruct*> testA;
//TestStruct** testA;
TestStruct xxx[100];
TestClass()
{
    testA.resize(100, NULL);
    //testA = new TestStruct*[100];
    for(unsigned int a = 0; a < 100; ++a)
    {
        testA[a] = new TestStruct;
    }
}
~TestClass()
{
    for(unsigned int a = 0; a < 100; ++a)
    {
        delete testA[a];
    }
    //delete [] testA;
    testA.clear();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    char inp;

    std::cin >> inp;
    {
        TestClass ttt[2];
        TestClass* bbbb = new TestClass[2];
        std::cin >> inp;
        delete [] bbbb;
    }
    std::cin >> inp;

    std::cin >> inp;
    return 0;
}

使用此代码,程序从大约 1 兆内存开始,上升到超过 8 兆,最后下降到 1.5 兆。额外的 0.5 meg 去哪儿了?我在粒子系统上遇到了类似的问题,但规模为数百兆字节。

我终其一生都无法弄清楚出了什么问题。

顺便说一句,使用数组(我已注释掉)大大减少了浪费的内存,但并没有完全减少它。我希望最后一个 cin 的内存使用量与第一个 cin 相同。

我正在使用任务管理器来监控内存使用情况。

谢谢。

4

1 回答 1

1

“我终其一生都无法弄清楚出了什么问题。”

大概什么都没有。

“[程序]在销毁所有对象后仍然在程序结束时使用更多内存。”

您不应该真正关心程序结束时的内存使用情况。任何现代操作系统都关心在进程结束时“释放”与进程相关的所有内存。(从技术上讲,就是简单地释放进程的地址空间。)

在程序结束时释放内存实际上会减慢程序的终止速度,因为它不必要地需要访问甚至可能位于交换空间上的内存页面。

额外的 0.5MB 可能保留在您的分配器中(malloc/free、new/delete、std::allocator)。这些分配器的工作方式通常是在必要时向操作系统请求内存,并在方便时将内存归还给操作系统。碎片化可能是分配器在某个时刻必须持有比严格要求更多的内存的原因之一。保留一些内存通常也更快,因为从操作系统请求内存很慢。

“我正在使用任务管理器来监控内存使用情况。”

测量内存使用情况实际上比观察单个数字更复杂,它需要很好地理解虚拟内存以及进程和操作系统之间的内存管理。不幸的是,我不能推荐任何适用于 Windows 的好工具。

总的来说,我认为您的简单程序没有问题。

于 2013-07-04T16:34:36.277 回答