這裏是我用來分配共享內存映射的一段代碼,我使用boost :: interprocess和managed shared segment segment,現在問題是我遇到了內存泄漏。以下給出的是最高產出。boost interprocess和valgrind
頂部輸出:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1. 27594 tpmon 20 0 46132 2140 1664 S 0.0 0.0 0:00.00 test_stub
2. 27594 tpmon 20 0 46132 2176 1664 S 0.0 0.0 0:00.01 test_stub
3. 27594 tpmon 20 0 46264 2248 1664 S 0.0 0.0 0:00.01 test_stub
4. 27594 tpmon 20 0 46264 2280 1664 S 0.0 0.0 0:00.01 test_stub
從頂部輸出顯而易見的是,駐留存儲器正不斷增加,在共享存儲器中的地圖我只有條目下面列出,作爲三元組:
Deb0 0 150520 Deb1 1 150520 Deb10 10 150520 Deb11 11 150520 Deb12 12 150520 Deb13 13 150520 Deb14 14 150520 Deb15 15 150520 Deb16 16 150520 Deb17 17 150520 Deb18 18 150520 Deb19 19 150520 Deb2 2 150520 Deb20 20 150520 Deb21 21 150520 Deb22 22 150520 Deb23 23 150520 Deb24 24 150520 Deb25 25 150520 Deb26 26 150520 Deb27 27 150520 Deb28 28 150520 Deb29 29 150520 D eb3 3 150520 Deb4 4 150520 Deb5 5 150520 Deb6 6 150520 Deb7 7 150520 Deb8 8 150520 Deb9 9 150520
這些不會被添加任何進一步,他們只是得到更新。
我採取的下一個步驟是運行的valgrind如下:
sudo -u tpmon valgrind --tool=memcheck --leak-check=yes ./bin/test_stub And below is the output: ==21404== Memcheck, a memory error detector ==21404== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==21404== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==21404== Command: ./bin/test_stub ==21404== Finished initializing TickerInfo Manager ^C==21404== ==21404== HEAP SUMMARY: ==21404== in use at exit: 60,627 bytes in 1,264 blocks ==21404== total heap usage: **5,059 allocs, 3,795 frees**, 812,123 bytes allocated ==21404== ==21404== 29 bytes in 1 blocks are possibly lost in loss record 2 of 7 ==21404== at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298) ==21404== by 0x3A7149C3C8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13) ==21404== by 0x3A7149CDE4: ??? (in /usr/lib64/libstdc++.so.6.0.13) ==21404== by 0x3A7149CF32: std::basic_string<char, std::char_traits<char>, > std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13) ==21404== by 0x40986F: main (test_stub.cxx:12)
從Valgrind的輸出很明顯,對於allocs人數比免費較大,但確實有任何真正的意義,在共享內存的情況下,我們希望分配的內存在進程退出後出現。
test_stub.cxx
#include <stdio.h>
#include <iostream>
#include<string>
#include <sstream>
using namespace std;
int main() {
TickerInfoManager * ticker_info_manager_inst = TickerInfoManager::get_instance("test");
char_allocator ca(ticker_info_manager_inst->get_managed_memory_segment().get_allocator<char>());
while(1) {
for(int i=0; i < 30; i++) {
basic_time now;
stringstream convert;
convert << i;
int curr_time = now.fullTime();
ticker_info_manager_inst->put_records(*(new tickerUpdateInfo(const_cast<char*>(("Deb"+convert.str()).c_str()), i, curr_time, ca)));
}
sleep(1);
}
//ticker_info_manager_inst->print_contents();
return 0;
}
TickerInfoManager.cxx
#include <TickerInfoManager.h>
#include <TickerInfoMangerImplementation.h>
TickerInfoManager::TickerInfoManager(const sharedMemoryNameT & name) : pInfoMangerImpl(new tickerInfoMangerImplementation(name)) {
}
TickerInfoManager* TickerInfoManager::get_instance(const sharedMemoryNameT & name) {
return (new TickerInfoManager(name));
}
bool TickerInfoManager::put_records(const tickerUpdateInfoT & record) {
return pInfoMangerImpl->put_records(record);
}
void TickerInfoManager::print_contents() {
return pInfoMangerImpl->print_contents();
}
bip::managed_shared_memory& TickerInfoManager::get_managed_memory_segment() {
return pInfoMangerImpl->get_managed_memory_segment();
}
TickerInfoMangerImplementation.cxx
#include <TickerInfoMangerImplementation.h>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream>
#include "basic_time.h"
using namespace boost::interprocess;
tickerInfoMangerImplementation::tickerInfoMangerImplementation(const sharedMemoryNameT & name): m_name(name),
m_managed_memory_segment(open_or_create, "test", 1000000),
p_ticker_info_map(m_managed_memory_segment.find_or_construct<KeyTickerCountMap>("TickerInfoMap")(std::less<SharedString>(), m_managed_memory_segment.get_segment_manager())) {
std::cout<<"Finished initializing TickerInfo Manager" << std::endl;
}
bool tickerInfoMangerImplementation::put_records(const tickerUpdateInfoT & record) {
//If the key has not been inserted, insert the key and update the map
KeyTickerCountMap::iterator iterator_to_map = p_ticker_info_map->find(record.m_id);
if(iterator_to_map == p_ticker_info_map->end()) {
p_ticker_info_map->emplace(record.m_id, std::make_pair(record.m_total_ticker_count, record.m_active_ticker_count));
}
else {
p_ticker_info_map->at(record.m_id) = std::make_pair(record.m_total_ticker_count, record.m_active_ticker_count) ;
}
//record.m_ca.deallocate(const_cast<char*> ((record.m_id).c_str()), record.m_id.length());
return true;
}
int tickerInfoMangerImplementation::calculate_historical_time_using_threshold(const thresholdT seconds) {
basic_time::Secs_t secs(seconds);
basic_time tick_time;
tick_time -= secs;
return (tick_time.fullTime());
}
void tickerInfoMangerImplementation::print_contents() {
KeyTickerCountMap::iterator map_iter = (*p_ticker_info_map).begin();
KeyTickerCountMap::iterator map_end = (*p_ticker_info_map).end();
for (; map_iter != map_end; ++map_iter) {
std::cout<< map_iter->first << " " << map_iter->second.first << " " << map_iter->second.second << std::endl;
}
}
TickerInfo.h
#ifndef __TICKER_INFO__
#define __TICKER_INFO__
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <iostream>
typedef boost::interprocess::managed_shared_memory::allocator<char>::type char_allocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, char_allocator> shm_string;
//Data to insert in shared memory
typedef struct tickerUpdateInfo {
shm_string m_id;
int m_total_ticker_count;
int m_active_ticker_count;
char_allocator m_ca;
tickerUpdateInfo(char * id,
int total_ticker_count,
int active_ticker_count,
const char_allocator &a)
: m_id(id, a),
m_total_ticker_count(total_ticker_count),
m_active_ticker_count(active_ticker_count),
m_ca(a) {
}
~tickerUpdateInfo() {
std::cout<< "Calling destructor" <<std::endl;
}
tickerUpdateInfo& operator=(const tickerUpdateInfo& other) {
if (this != &other) {
m_total_ticker_count = other.m_total_ticker_count;
m_active_ticker_count = other.m_active_ticker_count;
}
return *this;
}
} tickerUpdateInfoT;
#endif
**TickerInfoManager.h**
#ifndef __TICKER_INFO_MANAGER__
#define __TICKER_INFO_MANAGER__
#include <TickerInfoManagerConstants.h>
#include <TickerInfoMangerImplementation.h>
//class tickerInfoMangerImplementation;
class TickerInfoManager {
public:
static TickerInfoManager* get_instance(const sharedMemoryNameT & name);
bool put_records(const tickerUpdateInfoT & record);
TickerInfoManager(const sharedMemoryNameT & name);
void print_contents();
boost::interprocess::managed_shared_memory& get_managed_memory_segment();
private:
std::auto_ptr<tickerInfoMangerImplementation> pInfoMangerImpl;
};
#endif
TickerInfoMangerImplementation.h
#ifndef __TICKER_INFO_MANAGER_IMPL__
#define __TICKER_INFO_MANAGER_IMPL__
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/map.hpp>
//#include <TickerInfoManagerConstants.h>
#include <TickerInfo.h>
#include <vector>
#include <fire/HashMap.h>
#include <string>
typedef std::string sharedMemoryNameT;
typedef int thresholdT;
namespace bip = boost::interprocess;
//the strings also need to be assigned from the shared memory
typedef bip::allocator<void, bip::managed_shared_memory::segment_manager> VoidAllocator;
typedef bip::allocator<char, bip::managed_shared_memory::segment_manager> CharAllocator;
typedef bip::basic_string<char, std::char_traits<char>, CharAllocator> SharedString;
//Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
//so the allocator must allocate that pair.
typedef bip::allocator<std::pair<const SharedString, std::pair<int,int> >, bip::managed_shared_memory::segment_manager> MapValueTypeAllocator;
typedef bip::map<SharedString, std::pair<int,int>, std::less<SharedString>, MapValueTypeAllocator> KeyTickerCountMap;
//allocator for the string
typedef bip::allocator<SharedString, bip::managed_shared_memory::segment_manager> StringAllocator;
class tickerInfoMangerImplementation {
public:
tickerInfoMangerImplementation(const sharedMemoryNameT & name);
bool put_records(const tickerUpdateInfoT & record);
void print_contents();
bip::managed_shared_memory& get_managed_memory_segment() {
return m_managed_memory_segment;
}
private:
const sharedMemoryNameT m_name;
bip::managed_shared_memory m_managed_memory_segment;
bip::offset_ptr<KeyTickerCountMap> p_ticker_info_map;
int calculate_historical_time_using_threshold(const thresholdT seconds);
};
#endif
所以基本上碼流是這樣的:
從test_stub.cxx我們稱之爲put_records在TickerInfoManager ---- - >調用put_records(在tickerInfoManagerImplementation中)---> put_records在tickerInfoManagerImplementation中將數據插入駐留在shar中的映射編輯記憶。
我已經添加了完整的代碼,如果有人想重現這種情況。
我的問題是我該如何去調試這個問題,我不理解valgrind輸出正確嗎?
謝謝, Deb!
哇,然而在這四種情況中,你沒有得到任何感謝或顯然有任何upvote(op的唯一回復是對其他內容的間接思考,並且任何當前的+1都是我的)。不知道你爲什麼打擾?有耐心解釋的榮譽 - 爲了其他可能真正聽的人的利益 - 爲什麼他們不應該這樣編碼。 ;-) – 2016-02-03 00:19:47
@underscore_d老實說,我主要是回答學習自己。改進(設計)現有代碼是一門藝術。讓其他人從事其他工作的人員可以繼續工作是一項挑戰。我不是一個天賦的人才。我必須投入工作才能讓這些事情變得更好:) – sehe 2016-02-03 00:52:32