为什么我的RSS会随着堆栈分配的内存而增长

时间:2010-02-13 13:11:58

标签: c++ memory-management

我写了一个小型服务器应用程序。它将大量数据存储在字符串中。当压力测试它时,RSS内存增长(由$ top发现)。

我通过“仪器”运行程序 - Mac OS X内存泄漏应用程序,它只发现一些小漏洞 - 泄漏的内存是几百字节,程序不断增长。当深入搜索时,似乎有两个函数负责大部分内存占用:

std::string serialize()
{

 //Build basic message

 std::string result="";
        //std::cout << "result: " << result << "\n";
        result+=m_topic+d;
 //std::cout << "result: " << result << "\n";
 result+=m_message+d;
 //std::cout << "result: " << result << "\n";
 char buf[12];
 std::cout << m_severity << "\n";
 snprintf(buf, sizeof(buf), "%d", m_severity);
 //std::cout << "Buffer:" <<  buf << "\n";
 std::string temp(buf);
 result+=temp+d;
 //std::cout << "result: " << temp << "\n";

 int messagelength=strlen(result.c_str());
 snprintf(buf, sizeof(buf), "%d", messagelength);
 //std::cout << "Buffer:" <<  buf << "\n";
 std::string temp2(buf);
 temp2+=d;
 temp2+=result;
 //std::cout << "result: " << temp2 << "\n";
 return temp2;
}

std::string message::prettyPrint()
{
 struct tm *Sys_T= NULL;
 time_t Tval = 0;   
 Tval = time(NULL);
 Sys_T = localtime(&Tval);
 std::string date;
 char buf[10];
 sprintf(buf,"%d:%d:%d (%d/%d 2010)",Sys_T->tm_hour, Sys_T->tm_min, Sys_T->tm_sec, Sys_T->tm_mday, Sys_T->tm_mon);
 date+=std::string(buf);

 char sevbuf[10];
 sprintf(sevbuf,"%d",m_severity);

 delete Sys_T;
 std::string printed= "---------------------Message--------------------- \n";
 printed+= +"\n "+ date + ":  [[" +  getTopic() + "]]\n\n" +
 + " Message:" + m_message + "\n"
 + " Severity " + std::string(sevbuf) +" \n";
 //+ " Serialized " + serialize() + "\n";
 return printed;
}

正如您所看到的,这只是堆栈分配的对象。

与此同时,“仪器”内存观察器报告“活动”分配的内存数量不会增加。

我对编程或这些术语不熟悉 - 我的问题是:

  • 我的应用程序是否可以泄漏内存泄漏搜索应用程序未报告的内存?
  • RSS是不报告“活动”内存集还是历史记录集?

3 个答案:

答案 0 :(得分:2)

如果这是代码,那么在本节中你会严重损坏你的筹码:

 char buf[10];
 sprintf(buf,"%d:%d:%d (%d/%d 2010)",Sys_T->tm_hour, Sys_T->tm_min, Sys_T->tm_sec, Sys_T->tm_mday, Sys_T->tm_mon);

之后所有的赌注都没有了。既然你正在使用字符串,我建议使用stringstreams或boost :: format进行漂亮的打印。

编辑:在对另一个答案的评论中,你说“此外,记忆以极快的速度吃掉 - 比可接受的要快得多。你有什么想法如何追踪正在发生的事情?我已经彻底检查了明显错误的代码“。除了使用valgrind之外,您可以尝试用空的函数替换您怀疑的函数(即std::string serialize() { return ""; })并比较内存使用情况。这样你至少可以发现这些功能是否确实导致泄漏

答案 1 :(得分:1)

大多数服务器进程在运行时会增长,直到达到某种均衡大小。这并不意味着它们有内存泄漏 - 例如,服务器可以为长时间运行的任务分配内存,这些任务只会在数小时后释放。是的,泄漏检测工具可能被欺骗,同时给出误报和误报结果。

编辑:再看看你的代码 - 你有未定义的行为。当你说:

delete Sys_T;

您正在删除未使用新分配的内容。你不能这样做。 localtime的结果是在线程本地存储(可能)中,由库管理,而不是由你管理。

另外,虽然不是这样的错误,你为什么这么说:

int messagelength=strlen(result.c_str());

当你可以简单地使用

result.size()

答案 2 :(得分:1)

即使您的对象仅仅是堆栈分配,类实现也可以在堆中分配内存。例如,std::string将执行此操作。

在堆中分配和取消分配内存可能会导致碎片,这可以解释内存使用量的增加。见http://en.wikipedia.org/wiki/Malloc#Heap-based

编辑:仔细观察您的代码,还有其他问题 - 正如其他人所指出的那样。