我在下面的地图中存储了大约14GB的数据:
struct data
{
char* a;
char* b;
data(char* _a, char* _b)
{
int alen = strlen(a);
a = new char[alen+1];
strcpy(a,_a);
a[alen]='\0';
int blen = strlen(_b);
b = new char[ blen+1];
strcpy(b,_b);
b[blen]='\0';
}
~data()
{
delete [] a;
delete [] b;
}
};
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
map<const char*, data*, ltstr> m;
程序运行一定数量的记录(26293289中的10440440),并在一段时间后收到以下错误消息。
Program terminated with signal SIGKILL, Killed.
The program no longer exists.
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.25.el6.x86_64 libgcc- 4.4.5-6.el6.x86_64 libstdc++-4.4.5-6.el6.x86_64
我怎样才能避免以上终止?
服务器规范:
Mem: 24605344k total, 15148556k used, 9456788k free, 20892k buffers
Swap: 2097144k total, 161364k used, 1935780k free, 14469244k cached
答案 0 :(得分:4)
OOM killer可能正在踩踏并杀死你的进程。 Take a look in your logs可以肯定。
答案 1 :(得分:2)
如果不了解程序的更多细节,可以尝试对文件进行内存映射以减少内存使用量。
答案 2 :(得分:1)
由于您显然内存不足,显而易见的事情是减少您正在使用的内存量。一种可能性是使用类似Patricia trie的东西来存储数据而不是std::map
(通常使用红黑树)。
确切地说,这将获得多少取决于你的字符串中有多少冗余。在某种程度上,它还取决于您用作键的字符串的大小,以及您与它们一起存储的数据的大小。
根据具体情况,您可能还会考虑使用Huffman压缩等固定表格来存储您存储的字符串作为与每个键相关联的数据。虽然在其他情况下,Huffman压缩不一定是最有效的,但是使用固定表它具有与你在这里工作的单个字符串相当好地工作的优点。如果data
部分中的字符串很长(例如,两个字符串的平均值至少为8K),除了霍夫曼压缩之外,可能还值得应用LZ *族压缩,但如果它们很短(例如,任何小于至少几千字节的东西)LZ可能不会很好地工作(除非你愿意将字符串组合成块,所以你可能必须解压缩几千字节的其他字符串才能进入在您检索某些数据时,您在任何给定时间关心的一个。
虽然压缩通常比直接从内存访问数据更慢而不进行压缩/解压缩,但它通常仍然比从磁盘检索数据更快,如果你的物理内存耗尽并最终使用虚拟内存通常会发生
答案 3 :(得分:1)
我怎样才能避免上述终止?
重新思考你的设计。你想达到什么目的?特别是,为什么你需要一个内存中有2700万个条目的查找表?