0

我在以下地图中存储了大约 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
4

4 回答 4

4

OOM 杀手可能正在介入并杀死您的进程 。看看你的日志以确定。

于 2013-01-11T02:11:20.067 回答
2

在不了解程序的更多细节的情况下,您可能会尝试对文件进行内存映射以减少内存使用。

于 2013-01-11T02:14:36.737 回答
1

我怎样才能避免上述终止?

通过重新思考您的设计。你想达到什么目的?特别是,为什么需要一个在内存中有 2700 万个条目的查找表?

于 2013-01-11T02:31:19.450 回答
1

由于您显然内存不足,显而易见的事情是减少您正在使用的内存量。一种可能性是使用类似 Patricia trie 的东西来存储数据,而不是 a std::map(通常使用红黑树)。

确切的收益将取决于您的字符串中有多少冗余。在某种程度上,它还取决于您用作键的字符串的大小,以及您使用它们存储的数据的大小。

根据具体情况,您还可以考虑使用诸如 Huffman 压缩之类的方法和一个固定表来存储您作为与每个键关联的数据的字符串。尽管 Huffman 压缩在其他情况下不一定是最有效的,但使用固定表,它的优点是可以很好地处理单个字符串,就像您在此处使用的那样。如果字符串中的data部分很长(例如,两个字符串的平均长度至少为 8K),除了 Huffman 压缩之外,可能还值得应用 LZ* 系列压缩,但如果它们很短(例如,任何小于至少几个千字节)L​​Z 可能不会很好地工作(除非您愿意将字符串组合成块,因此您可能必须解压缩几千字节的其他字符串才能在任何给定时间找到您关心的字符串'正在检索一些数据。

虽然压缩通常比直接从内存访问数据而不压缩/解压缩要慢,但它通常仍然比从磁盘检索数据要快,如果您用完物理内存并最终使用虚拟内存,通常会发生这种情况。

于 2013-01-11T02:22:54.137 回答