這裏有沒有內存泄漏?爲什麼會立即銷燬共享指針泄漏內存?
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
的來電!) 我的假設是,在第一次調用得到了一些記憶,然後因爲我做什麼用第二次調用的智能指針會立即刪除它。簡單?但是,當我運行我的程序時,內存會隨着時間的推移而增加,跳躍。然而,當我在節目中唯一打電話給廣播()時,它不會!
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,克++ 4.4,助推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個線程池調用。我的20ms超時意味着每個計時器都會以50次/秒的速度調用broadcast()
。我在我的函數開始時設置了到期時間,並在接近結束時運行計時器。被遺忘的代碼並沒有那麼做;將調試信息輸出到std :: cout可能是佔用CPU最多的工作。我想有時可能會立即觸發計時器;但是,我仍然不明白這會是一個問題,更不用說造成內存泄漏。
(該程序運行正常,順便說一下,做了充分的任務即使;我只當我發現通過PS報告的內存使用量已經跳起來了疑惑。)
UPDATE:感謝答案和評論。我可以補充說,我將程序在每個系統上運行了幾個小時,內存使用量沒有再增加。 (當Centos版本第二次跳轉時,我也準備將其視爲一次性堆重組或其他東西)。無論如何,很高興知道我對智能指針的理解仍然健全,並且存在沒有我需要關心的線程的奇怪的角落案例。
1)您的代碼示例不能編譯。 2)在我[修復](http://ideone.com/FCPHf)之後,我將它運行在valgrind下。它不會泄漏。 – 2012-02-22 06:49:43
我懷疑你正在看到堆管理的效果,而不是泄漏(例如碎片等)。有時候堆管理器可能會給你一個新的內存塊,而不是重複使用現有的內存管理器來考慮性能,而且這種行爲是不確定的。如果你想真正檢查這些東西,請使用調試分配器(MSVC++隨附一個,對於GCC,你可以像Rob那樣使用Valgrind) – 2012-02-22 07:06:39
如果你顯示的代碼是程序唯一的東西,它可能是一個問題。但是,您可能也在做其他許多事情,並且可以輕鬆解釋其中的差異。 – 2012-02-22 07:09:43