c++ - 使用太多内存(我认为)

标签 c++ memory memory-management slowdown

我正在尝试运行一个程序来分析一堆包含数字的文本文件。文本文件的总大小约为 12 MB,我从 360 个文本文件中每一个提取 1,000 个 double 并将它们放入一个 vector 中。我的问题是,我在文本文件列表中完成了大约一半,然后我的计算机速度变慢,直到它不再处理任何文件。该程序不是无限循环,但我认为我有使用过多内存的问题。有没有更好的方法来存储这些不会占用太多内存的数据?

其他可能相关的系统信息:

运行 Linux

8 GB 内存

安装了 Cern ROOT 框架(虽然我不知道如何减少我的内存占用)

英特尔至强四核处理器

如果您需要其他信息,我会更新此列表

编辑:我运行了 top,我的程序使用了更多内存,一旦它超过 80%,我就终止了它。代码很多,所以我会挑出分配内存的位来共享。 编辑 2:我的代码:

void FileAnalysis::doWork(std::string opath, std::string oName)
{
//sets the ouput filepath and the name of the file to contain the results
outpath = opath;
outname = oName;
//Reads the data source and writes it to a text file before pushing the filenames into a vector
setInput();
//Goes through the files queue and analyzes each file
while(!files.empty())
{
    //Puts all of the data points from the next file onto the points vector then deletes the file from the files queue
    readNext();
    //Places all of the min or max points into their respective vectors
    analyze();
    //Calculates the averages and the offset and pushes those into their respective vectors
    calcAvg();
}
makeGraph();
}

//Creates the vector of files to be read
void FileAnalysis::setInput()
{
string sysCall = "", filepath="", temp;
filepath = outpath+"filenames.txt";
sysCall = "ls "+dataFolder+" > "+filepath;
system(sysCall.c_str());
ifstream allfiles(filepath.c_str());
while (!allfiles.eof())
{
    getline(allfiles, temp);
    files.push(temp);
}
}
//Places the data from the next filename into the files vector, then deletes the filename from the vector
void FileAnalysis::readNext()
{
cout<<"Reading from "<<dataFolder<<files.front()<<endl;
ifstream curfile((dataFolder+files.front()).c_str());
string temp, temptodouble;
double tempval;
getline(curfile, temp);
while (!curfile.eof())
{

    if (temp.size()>0)
    {
        unsigned long pos = temp.find_first_of("\t");
        temptodouble = temp.substr(pos, pos);
        tempval = atof(temptodouble.c_str());
        points.push_back(tempval);
    }
    getline(curfile, temp);
}
setTime();
files.pop();
}
//Sets the maxpoints and minpoints vectors from the points vector and adds the vectors to the allmax and allmin vectors
void FileAnalysis::analyze()
{
for (unsigned int i = 1; i<points.size()-1; i++)
{
    if (points[i]>points[i-1]&&points[i]>points[i+1])
    {
        maxpoints.push_back(points[i]);
    }
    if (points[i]<points[i-1]&&points[i]<points[i+1])
    {
        minpoints.push_back(points[i]);
    }
}
allmax.push_back(maxpoints);
allmin.push_back(minpoints);
}
//Calculates the average max and min points from the maxpoints and minpoints vector and adds those averages to the avgmax and avgmin vectors, and adds the offset to the offset vector
void FileAnalysis::calcAvg()
{
double maxtotal = 0, mintotal = 0;
for (unsigned int i = 0; i<maxpoints.size(); i++)
{
    maxtotal+=maxpoints[i];
}
for (unsigned int i = 0; i<minpoints.size(); i++)
{
    mintotal+=minpoints[i];
}
avgmax.push_back(maxtotal/maxpoints.size());
avgmin.push_back(mintotal/minpoints.size());
offset.push_back((maxtotal+mintotal)/2);

}

编辑 3:我在代码中添加了保留 vector 空间并添加了代码来关闭文件,但是在程序停止之前我的内存仍然被填充到 96%...

最佳答案

这可以无限优化,但我的第一 react 是使用 vector 以外的容器。请记住, vector 的存储空间是在内存中连续分配的,这意味着如果没有足够的当前空间来容纳新元素,添加额外的元素会导致整个 vector 的重新分配

尝试为常量插入优化的容器,例如队列或列表。

或者,如果需要 vector,您可以尝试预先分配预期的内存占用空间,以避免连续重新分配。请参阅 vector.reserve():Vector .请注意,保留容量以元素而非字节为单位。

int numberOfItems = 1000;
int numberOfFiles = 360;

size_type totalExpectedSize = (numberOfItems) * (numberOfFiles);
myVector.reserve( totalExpectedSize );

------------ 编辑以下代码发布------------

我最关心的是 analyze() 中的以下逻辑:

for (unsigned int i = 1; i<points.size()-1; i++) 
{     
    if (points[i]>points[i-1]&&points[i]>points[i+1])     
    {         
        maxpoints.push_back(points[i]);     
    }     
    if (points[i]<points[i-1]&&points[i]<points[i+1])     
    {         
        minpoints.push_back(points[i]);     
    } 
} 
allmax.push_back(maxpoints); 
allmin.push_back(minpoints); 

具体来说,我关心的是 allmax 和 allmin 容器,您正在将 maxpoints 和 minpoints 容器的拷贝推送到这些容器上。根据数据集,maxpoints 和 minpoints 容器本身可以使用此逻辑变得非常大。

多次 承担了容器拷贝的费用。真的有必要将 minpoints/maxpoints 容器复制到 allmax/allmin 中吗?如果不了解更多信息,就很难优化您的存储设计。

我在任何地方都没有看到 minpoints 和 maxpoints 实际上被清空了,这意味着随着时间的推移它们会变得非常大,并且它们对应于 allmin/allmax 容器的拷贝也会变得非常大。 minpoints/maxpoints 是否应该代表仅一个文件的最小/最大点?

作为示例,让我们看一下简化的 minpoints 和 allmin 场景(但请记住,这同样适用于 max,并且两者的规模都比此处显示的更大)。显然,这是一个旨在展示我的观点的数据集:

File 1: 2 1 2 1 2 1 2 1 2 1 2
minpoints: [1 1 1 1 1]
allmin:    [1 1 1 1 1]

File 2: 3 2 3 2 3 2 3 2 3 2 3
minpoints: [1 1 1 1 1 2 2 2 2 2]
allmin:    [1 1 1 1 1 1 1 1 1 1 2 2 2 2 2]

File 3: 4 3 4 3 4 3 4 3 4 3 4
minpoints: [1 1 1 1 1 2 2 2 2 2 3 3 3 3 3]
allmin:    [1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3]

还有其他优化和批评要进行,但现在我将其限制为尝试解决您的直接问题。您能否发布makeGraph() 函数,以及涉及的所有 容器的定义(points、minpoints、maxpoints、allmin、allmax)?

关于c++ - 使用太多内存(我认为),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6333645/

相关文章:

c++ - 如何在运行时查看 C 程序的内存布局?

c++ - OpenCV VideoCapture 仅在第一次调用 glutDisplayFunc 回调时返回空帧

c - C语言中的标识符存放在哪里

c++ - std::function<> 和标准函数指针之间的区别?

对 C 中的指针和在内存地址处更改数据感到困惑

r - 以更快的方式(使用更少的内存)编写 ifelse()

iphone - 释放 CFString

c++ - Stroustrup书与C++ Standard之间的明显矛盾

c++ - 对于嵌套模板,什么时候 `>>` 成为标准 C++(而不是 `>>` )?

c++ - 将 QByteArray 从大端转换为小端