Why does my RSS grow with stack allocated memory
I have written a small server application. It stores a lot of data in strings. When stresstesting it, RSS memory grows (spotted by $top).
I have ran the program through "Instrument" - Mac OS X memory leak applicaton and it find only some minor leaks - the memory leaked was a couple of hundred bytes and the program continuously grows. When searching deeper, it seems like two functions is responsible for a large majority of the memory footprint:
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;
}
and
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 + ": [[" + getT开发者_开发知识库opic() + "]]\n\n" +
+ " Message:" + m_message + "\n"
+ " Severity " + std::string(sevbuf) +" \n";
//+ " Serialized " + serialize() + "\n";
return printed;
}
As you can see this is merely stack allocated objects.
At the same time, the "Instrument" memory observer reports that the number of "active" allocated memory does not grow.
I am not so familiar with programming or these terms - my question is:
- Can my application leak memory that is not reported by memory leak searching application?
- Is RSS not reporting the "active" memory set but also the historical ones?
If that's the code verbatim, you are damaging your stack badly in this section:
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);
All bets are off after that. Since you are using strings anyway, I'd suggest using stringstreams or boost::format for pretty printing.
Edit: In a comment to another answer you say "Also the memory is eaten with tremendous pace - much faster than acceptable. Do you have any ideas how to track down what is happening? I have thoroughly checked through the code for obvious mistakes". Apart from using valgrind, you could try to replace the functions you suspect with empty ones (i.e. std::string serialize() { return ""; }
) and compare memory usage. That way you can at least find out whether these functions are indeed causing the leaks
Even though your objects are merely stack allocated, the class implementations may allocate memory in the heap. For example, std::string
will do this.
Allocating and deallocating memory in the heap can lead to fragmentation, which would explain the increased memory usage. See http://en.wikipedia.org/wiki/Malloc#Heap-based
Edit: Looking closer at your code, there are other problems -- as the others have pointed out.
Most server processes grow as they run, until they reach some equilibrium size. This doesn't mean they have a memory leak - for example a server can allocate memory to long-running tasks which only gets freed hours later. And yes, leak detection tools can be fooled, giving both false positive and false negative results.
Edit: Just had another look at your code - you have undefined behaviour. When you say:
delete Sys_T;
you are deleting something not allocated by you with new. You must not do that. The result of localtime is in thread local storage (probably) and is managed by the library, not by you.
Also, though not an error as such, why are you saying:
int messagelength=strlen(result.c_str());
when you could simply use
result.size()
精彩评论