我目前正在开发一个项目,我需要为我的地图任务提供内存结构。我做了一些计算,我可以说每个地图任务我不需要超过600MB的内存。 但问题是,经过一段时间我有java堆空间问题或gc开销限制。我不知道这怎么可能。
以下是一些更多细节。我有两个四核系统,12GB内存。这意味着我可以同时运行多达8个地图任务。我正在构建一棵树,所以我有一个迭代算法,可以为每个树级别执行map-reduce作业。我的算法适用于小型数据集,但是对于中型数据集存在堆空间问题。我的算法到达某个树级别然后它离开堆空间,或者有gc开销问题。那时,我做了一些计算,我发现每个任务都不需要超过100MB的内存。所以对于8个任务,我使用大约800MB的内存。我不知道发生了什么事。我甚至用这些行更新了我的hadoop-env.sh文件:
export HADOOP_HEAPSIZE=8000
export HADOOP_OPTS=-XX:+UseParallelGC
有什么问题?这些行是否甚至覆盖了我的系统的java选项?使用parallelGC是我在互联网上看到的,并且建议在拥有多个核心时使用。
edits
这里有一些监控堆空间和总内存后的编辑。 当同时运行6个任务时,我消耗大约3500MB的RAM。这意味着jobtracker,tasktracker,namenode,datanode,secondary namenode我的操作系统和6个任务都使用3500 RAM,这是一个非常合乎逻辑的大小。那么为什么我会获得gc开销限制? 我对每个树级别都遵循相同的算法。唯一改变的是每个树级别的节点数量。在树级别拥有许多节点,不会给我的算法增加太多开销。那么为什么gc不能很好地工作呢?
答案 0 :(得分:5)
如果最大内存大小没有改变,它将是主内存的1/4,即大约3 GB加上非堆使用的一些开销可能是3.5 GB。
我建议你试试
export HADOOP_OPTS="-XX:+UseParallelGC -Xmx8g"
将最大内存设置为8 GB。
默认情况下,最大堆大小是内存的1/4(除非您在Windows上运行32位JVM)。因此,如果忽略最大堆大小,它仍将是3 GB。
无论您使用的是一台GC还是另一台GC,在内存不足时都没有太大区别。
我建议您使用-XX:+HeapDumpOnOutOfMemoryError
进行堆转储并在分析器中读取此内容,例如VisualVM,看看它为什么要使用这么多内存。