Scala Spark:分区的增量collect()会导致堆中的OutOfMemory

Scala Spark:分区的增量collect()会导致堆中的OutOfMemory,scala,apache-spark,garbage-collection,out-of-memory,Scala,Apache Spark,Garbage Collection,Out Of Memory,我有以下代码。本质上,我需要将RDD打印到控制台,所以我通过每个分区收集RDD,将大RDD收集到更小的块中。这是为了避免一次收集整个RDD。在监视堆和GC日志时,似乎没有任何东西是GC的。堆一直在增长,直到遇到OutOfMemory错误。如果我的理解是正确的,在下文中,一旦对收集的RDD执行了println语句,就不需要它们了,所以GC是安全的,但这不是我在GC日志中看到的每次收集调用都会累积到OOM。有人知道为什么收集的数据没有被GC'd吗 val writes = partitions.f

我有以下代码。本质上,我需要将RDD打印到控制台,所以我通过每个分区收集RDD,将大RDD收集到更小的块中。这是为了避免一次收集整个RDD。在监视堆和GC日志时,似乎没有任何东西是GC的。堆一直在增长,直到遇到OutOfMemory错误。如果我的理解是正确的,在下文中,一旦对收集的RDD执行了println语句,就不需要它们了,所以GC是安全的,但这不是我在GC日志中看到的每次收集调用都会累积到OOM。有人知道为什么收集的数据没有被GC'd吗

 val writes = partitions.foreach { partition =>
      val rddPartition = rdds.mapPartitionsWithIndex ({ 
        case (index, data) => if (index == partition.index) data else Iterator[Words]()
      }, false).collect().toSeq
      val partialReport = Report(rddPartition, reportId, dateCreated)
      println(partialReport.name) 
    }
collect()
创建一个包含RDD所有元素的数组

在完全创建之前,不能对其进行垃圾收集!因此出现了OOM


根据
报表
实际执行的操作,可能有办法解决此问题。

如果数据集很大,很可能主节点无法处理它,将关闭。您可以尝试将它们写入文件(例如saveAsTextFile),然后再次读取每个文件

如果您阅读了我的描述,我清楚地说明我们收集每个分区,我们这样做是为了避免收集整个RDD。分区不一定很小。但为什么它会在堆中累积?一旦打印完成,就应该是GCd。我的问题是,为什么收集的数据在堆中积累。问题是,驱动程序的堆是500MB,而不是我们配置的8GB。所以驱动程序实际上并没有足够的内存来同时执行程序和GC。因此,GC无法跟上应用程序的执行,并最终耗尽内存。在VisualVM的帮助下我们才看到这个。。。