0

我想在 Hadoop 框架中计算多路连接。当每个关系的记录从阈值开始变大时,我面临两个内存问题,

1) 错误:超出 GC 开销限制,

2) 错误:Java 堆空间。

阈值是链连接和星形连接的 1.000.000 / 关系。

在连接计算中,我使用了一些哈希表,即

Hashtable< V, LinkedList< K>> ht = new Hashtable< V, LinkedList< K>>( someSize, o.75F);

当我对输入记录进行哈希处理时会出现这些错误,并且暂时只会出现这些错误。在散列期间,我有很多 for 循环,它们会产生很多临时对象。出于这个原因,我得到了 1) 问题。所以,我通过设置 K = StringBuilder 解决了 1) 问题,这是一个最终类。换句话说,我减少了临时对象的数量,只有少数对象的值、内容会发生变化,但它们本身不会发生变化。

现在,我正在处理 2) 问题。我通过在文件 $HADOOP_HOME/hadoop/conf/hadoop-env.sh 中设置适当的变量来增加集群中每个节点的堆空间。问题仍然存在。我使用 VisualVM 对堆进行了非常基本的监控。我只监控主节点,尤其是 JobTracker 和本地 TaskTracker 守护进程。在此监视期间,我没有注意到任何堆溢出。PermGen 空间也没有溢出。

所以目前,在声明中,

Hashtable< V, LinkedList< K>> ht = new Hashtable< V, LinkedList< K>>( someSize, o.75F);

我正在考虑设置 V = SomeFinalClass。这个 SomeFinalClass 将帮助我保持低对象数量,从而降低内存使用量。当然,默认情况下 SomeFinalClass 对象将具有独立于其内容的相同哈希码。所以我将无法使用这个 SomeFinalClass 作为上面哈希表中的键。为了解决这个问题,我正在考虑覆盖默认的 hashCode() 方法和类似的 String.hashCode() 方法。此方法将根据 SomeFinalClass 对象的内容生成哈希码。

您对上述问题和解决方案有何看法?你会怎么办?

我还应该监视 DataNode 守护进程吗?上面的两个错误都是TaskTracker错误,DataNode错误还是两者兼而有之?

最后,上述解决方案能否解决任意数量的记录/关系的问题?还是迟早我会再次遇到同样的问题?

4

1 回答 1

0

使用 ArrayList 而不是 LinkedList,它将使用更少的内存。

另外我建议使用 HashMap 而不是 Hastable,因为后者是一个遗留类。

于 2013-09-23T19:09:12.543 回答