Почему мой RSS растет с выделенной памятью стека - PullRequest
0 голосов
/ 13 февраля 2010

Я написал небольшое серверное приложение.Он хранит много данных в строках.При стресс-тестировании объем памяти 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;
}

Как вы можете видеть, это всего лишь стек выделенных объектов.

В то же время обозреватель памяти «Инструмент» сообщает, что количество «активной» выделенной памяти не увеличивается.

Я не очень знаком с программированием или этими терминами - мой вопросis:

  • Может ли мое приложение утекать память, о которой не сообщает приложение поиска утечек памяти?
  • RSS не сообщает об "активном" наборе памяти, но также и о хронологических?*

Ответы [ 3 ]

2 голосов
/ 13 февраля 2010

Если это дословно код, вы сильно повредите свой стек в этом разделе:

 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 голос
/ 13 февраля 2010

Даже если ваши объекты просто выделены в стеке, реализации классов могут распределять память в куче. Например, std::string сделает это.

Выделение и освобождение памяти в куче может привести к фрагментации, что объясняет увеличение использования памяти. Смотри http://en.wikipedia.org/wiki/Malloc#Heap-based

Редактировать: Если присмотреться к вашему коду, есть другие проблемы - как уже отмечали другие.

1 голос
/ 13 февраля 2010

Большинство серверных процессов растут во время работы, пока не достигнут некоторого равновесного размера. Это не означает, что у них есть утечка памяти - например, сервер может выделить память для долгосрочных задач, которые освобождаются только спустя часы. И да, инструменты для обнаружения утечек могут быть обмануты, давая ложноположительные и ложноотрицательные результаты.

Редактировать: Просто еще раз взглянул на ваш код - у вас неопределенное поведение. Когда вы говорите:

delete Sys_T;

Вы удаляете что-то, что не выделено вами новым. Вы не должны этого делать. Результат локального времени находится в локальном хранилище потока (вероятно) и управляется библиотекой, а не вами.

Кроме того, хотя это и не ошибка как таковая, почему вы говорите:

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

когда вы можете просто использовать

result.size()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...