Есть ли здесь утечка памяти?
class myclass : public boost::enable_shared_from_this<myclass>{
//...
void broadcast(const char *buf){
broadcast(new std::string(buf));
}
void broadcast(std::string *buf){
boost::shared_ptr<std::string> msg(buf);
}
//...
};
(Это урезанная версия, которая все еще показывает проблему - обычно я выполняю реальную работу во время этого второго broadcast
вызова!) Я предполагаю, чтопервый вызов получает немного памяти, затем, поскольку я ничего не делаю с умным указателем, второй вызов немедленно удалит его.Просто?Но когда я запускаю свою программу, память увеличивается со временем, в прыжках.Тем не менее, когда я закомментирую единственный вызов в программе для broadcast (), он не будет!
Вывод ps для версии без broadcast()
:
%CPU %MEM VSZ RSS TIME
3.2 0.0 158068 1988 0:00
3.3 0.0 158068 1988 0:25 (12 mins later)
При вызовеbroadcast()
(в Ubuntu 10.04, g ++ 4.4, boost 1.40)
%CPU %MEM VSZ RSS TIME
1.0 0.0 158068 1980 0:00
3.3 0.0 158068 1988 0:04 (2 mins)
3.4 0.0 223604 1996 0:06 (3.5 mins)
3.3 0.0 223604 2000 0:09
3.1 0.0 223604 2000 2:21 (82 mins)
3.1 0.0 223604 2000 3:50 (120 mins)
(Видя, что скачок на 3 минуты воспроизводим в те несколько раз, которые я до сих пор пробовал.)
При вызове broadcast()
(в Centos 5.6, g ++ 4.1, boost 1.41)
%CPU %MEM VSZ RSS TIME
0.0 0.0 51224 1744 0:00
0.0 0.0 51224 1744 0:00 (30s)
1.1 0.0 182296 1776 0:02 (3.5 mins)
0.7 0.0 182296 1776 0:03
0.7 0.0 182296 1776 0:09 (20 mins)
0.7 0.0 247832 1788 0:14 (34 mins)
0.7 0.0 247832 1788 0:17
0.7 0.0 247832 1788 0:24 (55 mins)
0.7 0.0 247832 1788 0:36 (71 mins)
Вот как вызывается broadcast()
(из таймера boost :: asio), и теперь я 'Мне интересно, может ли это иметь значение:
void callback(){
//...
timer.expires_from_now(boost::posix_time::milliseconds(20));
//...
char buf[512];
sprintf(buf,"...");
broadcast(buf);
timer.async_wait(boost::bind(&myclass::callback, shared_from_this() ));
//...
}
(обратный вызов находится в том же классе, что и функция широковещания)
У меня 4 таких таймера, и мой io_service.run()
вызываетсяпулом из 3-х потоков.Мой тайм-аут 20 мс означает, что каждый таймер вызывает broadcast()
50 раз в секунду.Я устанавливаю срок действия в начале своей функции и запускаю таймер ближе к концу.Проверенный код не так уж много делает;вывод отладочной информации в std :: cout, пожалуй, самая трудоемкая работа.Я полагаю, что это может быть возможно, таймер срабатывает сразу же иногда;но, тем не менее, я не могу понять, как это может быть проблемой, не говоря уже о том, чтобы вызвать утечку памяти.
(Кстати, программа работает нормально, даже когда выполняет свои полные задачи; у меня возникли подозрения только тогда, когда язаметил, что использование памяти, о котором сообщает ps, увеличилось.)
ОБНОВЛЕНИЕ: Спасибо за ответы и комментарии.Могу добавить, что я оставил программу работающей на каждой системе еще на пару часов, и использование памяти больше не увеличивалось.(Я также был готов отклонить это как одноразовую реструктуризацию кучи или что-то подобное, когда версия Centos подскочила во второй раз.) В любом случае, приятно знать, что мое понимание умных указателей все еще здраво, и что естьнет странного углового случая с потоками, о котором я должен беспокоиться.