使用缓冲区写入文件时c ++内存泄漏
Posted
技术标签:
【中文标题】使用缓冲区写入文件时c ++内存泄漏【英文标题】:c++ memory leaks when using buffer to write to file 【发布时间】:2012-10-22 09:42:30 【问题描述】:我有一个在 Linux 系统上被激活的具有许多线程的系统。每个线程分配一个特定大小的缓冲区,当该缓冲区已满时将其写入文件。每个线程都有自己的缓冲区,并将缓冲区写入不同的文件。我发现当我将缓冲区大小设置为相对较大(1M 或更大)时,我开始遭受内存泄漏的困扰。但是,当缓冲区很小(大约 1K 或更少)时,我没有这些内存泄漏。
有人知道这是什么原因吗?更重要的是我该如何克服这个问题?使用较小的缓冲区会极大地影响我的系统性能。
写入缓冲区 - 否则如果(m_bUseBuffer) //数据缓冲区现在已满 if (m_nBufferSize+pi_nDataLength >= cMaxSizeQLoaderFileBuffer) hRes = WriteDataToFile();
if (SUCCEEDED(hRes))
if (m_nBufferSize+pi_nDataLength <= cMaxSizeQLoaderFileBuffer)
memcpy(m_sBuffer+m_nBufferSize,pi_pData,pi_nDataLength);
m_nBufferSize += pi_nDataLength;
m_nBufferLinesCounter++;
//need to write buffer to file otherwise next time we write the file will be too large.
if (m_nBufferLinesCounter + m_nQLoaderFileLinesCounter >= m_nQLoaderFileMaxLines)
hRes = WriteDataToFile();
将缓冲区写入文件-
hRes = OpenFile();
if (SUCCEEDED(hRes))
m_fQLoaderFile.write(m_sBuffer,m_nBufferSize);
m_fQLoaderFile.flush();
m_nBufferSize = 0;
m_nQLoaderFileLinesCounter += m_nBufferLinesCounter;
m_nBufferLinesCounter = 0;
when 来自 type-std::ofstream
【问题讨论】:
如果不查看一些重现的示例代码就无法看到。 你能给我们一些代码吗?含糊的问题产生含糊的回答 你怎么知道你看到了内存泄漏?也许问题实际上是内存碎片? 我用一个简单的顶部看到了泄漏。下面我尽量给出相关代码。 top 并不表示内存泄漏。当您释放内存时,它会返回到您的程序,它不必返回到系统。这只发生在您退出程序时。由于 top 指示系统可用的内存,它可以指示您的程序正在使用越来越多的内存,但这本身并不意味着内存泄漏。如果您希望将释放的内存返回给系统,您将不得不进行更复杂且特定于平台的内存管理。 【参考方案1】:因为你的问题太模糊,我只能给你一个笼统的答案:用valgrind
检查你的代码,它会报告所有的内存泄漏。
顺便说一句,如果您的代码是正确的,那么缓冲区大小就无关紧要了。
【讨论】:
Valgrind- 我试过没有给我任何回应。我猜代码有问题,但这种行为很奇怪。 我假设您看到了 valgrind 标头(它开始等)。如果没有报告,没有memleak...(注意:只要有分配空间的指针,就不会被认为是泄漏)【参考方案2】:是否可以将线程(或其缓冲区)包装在RAII 包装器中?也就是说,堆栈分配的包装对象带有重载的私有 new 运算符(以防止意外的堆分配),缓冲区的堆分配发生在构造函数中,而取消分配发生在析构函数中?
或者:固定长度(堆栈分配)缓冲区是否适合您的问题?
【讨论】:
我会尝试使用固定长度并告诉你它是怎么回事。【参考方案3】:如果没有更多细节,几乎不可能回答这个问题。正如@karoly 建议的那样,如果您的代码正确 - 缓冲区大小无关紧要。
当缓冲区大小很重要时,我能想到的一件事是,当缓冲区大小太大时,某些分配可能会失败。然后,当这种情况发生时,可能您的代码在这种情况下不能很好地清理(您没有捕获异常,或者没有测试错误条件)。
【讨论】:
但是我分配了一次缓冲区,并在整个代码中重用它而不重新分配它。以上是关于使用缓冲区写入文件时c ++内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章
使用 AVAssetWriter 将大量图像写入视频文件时的高峰值内存使用率
C 语言文件操作 ( fflush 函数 | 刷新缓冲区示例代码 )
在写入已装入目录中的文件时,docker容器会增加内存使用量