我遇到了一种情况(在Win32上),即使在一系列附加类型操作之后表面上清除了std :: ostringstream对象,该对象仍继续消耗进程内存。请看一下这个C ++片段:

int main(void)
{
    std::ostringstream cOutputLogStream;

    // Random long string
    std::string sTest = "jkspoiauyeraspfoiusdfsdfekgpweojkgpwoekpokgkpgeopoegwj";

    std::string sEmpty = "";

    int n = 0;
    int looper = 0;

    while (n++ < 100000)
    {
        while (looper++ < 45)
        {
            cOutputLogStream  <<  s;
        }

        cOutputLogStream.str(sEmpty);
        cOutputLogStream.clear();

        // This should give the heap manager a chance to consolidate
        // fragmented memory blocks
        Sleep(1);
    }
}


在执行内部while()循环期间,在任务管理器中观察进程的内存使用情况会显示出持续的上升,最终逐渐趋于平稳。但是,这种平衡是在重复抛出错误std :: bad_alloc的同时发生的。这可能表明堆内存已用完,或者所请求的块大小在连续空间中不可用。

其他人是否曾使用ostringstream对象经历过这种泄漏现象,还有哪些其他替代对象可以替代此片状对象呢?

非常感谢!

最佳答案

我看不出这段代码如何重现该问题。循环器增加到45后,应该完成所有内存的消耗。

通用诊断是程序很少设法消耗所有可能的可用虚拟内存。它将首先在堆中找到足够大的存储字节流缓冲区的连续字节块而死。这称为地址空间碎片,您对此无能为力。您的Sleep()调用肯定不会做任何有用的事情,合并分配的堆块需要使用垃圾回收器。

另一个相当标准的陷阱是使用TaskMgr.exe诊断内存使用情况。它通常显示工作集,即映射到RAM的虚拟内存量。通常,这只是程序消耗的虚拟内存量的一小部分,无法真正衡量程序消耗了多少虚拟内存。或告诉您有关该地址空间碎片的任何信息。

SysInternals的VMMap实用程序可以向您显示程序如何使用虚拟内存。

10-08 03:54