我写了一个小型服务器应用程序。它将大量数据存储在字符串中。当压力测试它时,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;
}
正如您所看到的,这只是堆栈分配的对象。
与此同时,“仪器”内存观察器报告“活动”分配的内存数量不会增加。
我对编程或这些术语不熟悉 - 我的问题是:
答案 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
编辑:仔细观察您的代码,还有其他问题 - 正如其他人所指出的那样。