例如,假设你在一个节点上安装运行ZooKeeper、CLDB、MFS、JobTracker、TaskTracker、NFS、the GUI、HBase Master 和HBase RegionServer。这么多的服务运行在一个节点上,而且每个服务都需要内存,所以warden会将内存按照百分比分配给每个服务,剩下的将会分配 给节点上的map/reduce 实例。如果你分配给这些服务总共60%还有5%为系统预留,那么还有35%分给节点上的map/reduce实例。如果这个节点有10G的内存,将会有3.5G分给 map/reduce 任务。如果你有 6个map slot和4个reduce slot。如果内存是平均分配的,终每个JVM的内存限制为350MB。如果你需要512MB内存来运行你的map任务,那么默认设置的情况下是不会运行的,你会遇到Java堆空间错误。
  当管理实例内存的时候会意识到还有其它问题。不要强制节点去使用大量的交换空间(swap space)或者触发频繁内存分页读写磁盘。如果你通过显式的在mapred.map.child.java.opts设置“-Xmx500m”来改变提交的作业,将会重写安全的内存限制。但实际上你并没有额外的物理内存。虽然 map/reduce 实例仍能启动,但是会强制使用大量的交换空间,而且无法依赖内核的OOM killer或者其他的方法来防止这种情况发生。如果真的发生这种情况,无法指望节点启动大量分页来迅速恢复。如果只是增加了实例的JVM内存,同时继续在节点上启动相同数量的实例。你会申请更多的内存,需要注意不要超额申请。如果超额申请太多的话,会导致大量的分页,这样节点可能会被挂 起再也无法恢复。除非重启电源。
  所以如果你给每个实例JVM增加内存的话,需要通过TaskTrackers来减少分配给map/reduce task slot数量。
  这是一个很复杂的情况,因为如果你在集群上并发执行不同的作业,可能来自一个作业(JobA)的实例需要大量的内存,来自另外一个作业(JobB)的实例只需要很少的内存。因此,如果你减少map/reduce slot的数量,会发现会有足够的内存来运行来自JobB任务(task)。但是却没有足够的内存提供给JobA。所以关键是找到一个平衡点,一个可以允许进行一些超额申请却不会导致节点被挂起的平衡点。
  为了协助这个任务,TaskTracker 将会着眼于当前所有在运行的 map/reduce tasks 所使用的内存数量。不是只看这些任务的大内存限制,而是所有运行中的实例实际利用的内存总数。当消耗的内存达到一定级别,TaskTracker 会杀死一些运行的实例来释放内存,以便其他的实例能正常执行完并且不会造成节点上的分页过多。
  举个例子,如果你想在一个小型的集群或者单一节点上运行wordcount示例,碰到“Java堆空间”错误,简单快的解决方法是通过编辑/opt/mapr/hadoop/hadoop-0.20.2/conf/mapred-site.xml中的设置来减少 map/reduce 实例 slot的数量:
  mapred.tasktracker.map.tasks.maximum
  mapred.tasktracker.reduce.tasks.maximum
  将实例的slot的数量设置为小于当前计算结果是非常重要的。当前计算的数量可以通过进入JobTracker web界面来确定。例如,如果你有一个TaskTracker ,显示它有6个mpa slot和4个 reduce slot,那么你应该设置 3个map slot、2个 reduce slot。然后通过下面这行命令重启节点上的TaskTracker进程:
  maprcli node services -nodes -tasktracker restart
  减少slot的数量重新启动后,重新提交wordcount作业。如果没有额外内存申请,每个实例、JVM都会分配到更多的内存。这是一个安全的解决方法,节点不会产生大量分页。这是一种简单的解决方案,不需要大量计算内存。这也是快速的方法,只需要编辑下配置文件并重启下服务好了。
  为了避免Java堆空间错误,记住下面这些步骤:
  估算你的实例需要消耗多少内存。
  确保TaskTracker 启动你的实例时,JVM内存的限制要大于等于你预计的内存需求。
  记住,启动这些JVM是有默认设置的,除非你显式的重写过这些设置。在CPU核心数和物理内存已经平衡并运行服务的节点上,默认设置并不适用。
  不要迫使节点大量的使用交换空间或者频繁的将内存分页读写到磁盘上。
  将实例slot数量设置为小于JobTracker web GUI计算值。