Scala 如何在小函数范围内的小数组缓冲区中避免OutOfMemoryError?

Scala 如何在小函数范围内的小数组缓冲区中避免OutOfMemoryError?,scala,apache-spark,Scala,Apache Spark,scanFolder函数正在运行,但有时会产生以下异常 对象MyClass{ //…等等 val fs=FileSystem.getnew配置 //等等 val dbs=scanFolderwarehouse val dbs_prod=dbs.filter s=>db_regex.findFirstIns.isDefined 对于db} }//p循环,分区 allVals.append s'${cutPathdb}','${cutPatht}',${parts},${size},$dbHoje'

scanFolder函数正在运行,但有时会产生以下异常

对象MyClass{ //…等等 val fs=FileSystem.getnew配置 //等等 val dbs=scanFolderwarehouse val dbs_prod=dbs.filter s=>db_regex.findFirstIns.isDefined 对于db} }//p循环,分区 allVals.append s'${cutPathdb}','${cutPatht}',${parts},${size},$dbHoje' 如果TRU计数大于0,则contaEstranhos+=1 } def scanFolderthePath:String,toCut:Boolean=false:ArrayBuffer[String]={ val lst=ArrayBuffer[字符串] fs.listStatus新路径path.foreach x=>lst.append cutPathx.getPath.toString,toCut 一级分类 } } 错误:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
        at java.util.Arrays.copyOf(Arrays.java:3332)
        at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
        at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
        at java.lang.StringBuilder.append(StringBuilder.java:136)
        at org.apache.hadoop.fs.Path.<init>(Path.java:109)
        at org.apache.hadoop.fs.Path.<init>(Path.java:93)
        ...
最终错误消息,停止程序:

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "SparkListenerBus"
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
19/10/16 18:42:14 WARN DefaultPromise: An exception was thrown by org.apache.spark.network.server.TransportRequestHandler$$Lambda$16/773004452.operationComplete()
java.lang.OutOfMemoryError: Java heap space
19/10/16 18:42:14 WARN DefaultChannelPipeline: An exception 'java.lang.OutOfMemoryError: Java heap space' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception:
java.lang.OutOfMemoryError: Java heap space

我对你的具体问题没有答案。但我想给出一些可能有用的建议:

更喜欢流式处理,即避免循环。使用map、filter、fold等。不要在代码片段中使用像lst和allVars这样的全局状态。 避免不必要的分类。scanFolder以排序结束,没有明确的原因。 考虑为任务添加更多堆内存,这将降低GC压力。 使用JVM探查器缩小对内存分配贪婪的特定代码段。在你的情况下,你不需要,因为这是很明显的。但在更棘手的情况下,这可能会有很大帮助。
在@SergeyRomanovsky提供了很好的线索之后,我解决了这个问题。。。这是我第一次在终端上使用Spark Shell sshell的片段

通过最流行的指令添加内存,sshell-驱动程序内存12G-执行程序内存24G

删除最内部和最有问题的循环,将int减少到parts=fs.listStatus new Patht.length,并将其封装到try指令中

添加多个try指令以在try.length成功后运行最内部的循环

将ArrayBuffer[]变量减少到最小,删除旧的scanFolder

完整片段:

// ... val allVals=ArrayBuffer[字符串] //for循环: var parts=-1 变量大小=-1L 请尝试{//在循环过程中可能会丢失分区文件,生成未找到的文件 val pp=fs.listStatus新路径 零件=pp.长度 pp.foreach p=>{ 请尝试{//超时和其他文件系统错误 size=size+fs.getContentSummaryp.getPath.getLength }catch{case}:Throwable=>} }//p循环,分区 }catch{case}:Throwable=>} allVals.append s'${dbCut}','${cutPatht}',$parts,$size,'$dbHoje'
PS:对于编译器上的第1项,请使用SparkSession.builder。configspark.executor.memory,24G.configspark.driver.memory,12G

之所以会出现这种情况,是因为您在短时间内创建了太多对象,以至于GC几乎没有时间清理它们。罪魁祸首可能是新路。。。或者x.getPath.toStringHi@jrook,有意义!,包含大量p.getPath的最密集的循环是最内部的、最复杂的循环。。。我编辑了问题,替换了。。。做点什么。。。到现实生活的片段。也许现在你可以看到问题的真正原因了谢谢,很好的线索!关于更多堆内存?
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "SparkListenerBus"
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
19/10/16 18:42:14 WARN DefaultPromise: An exception was thrown by org.apache.spark.network.server.TransportRequestHandler$$Lambda$16/773004452.operationComplete()
java.lang.OutOfMemoryError: Java heap space
19/10/16 18:42:14 WARN DefaultChannelPipeline: An exception 'java.lang.OutOfMemoryError: Java heap space' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception:
java.lang.OutOfMemoryError: Java heap space