在Spark中,我从函数中读取HDFS中大约1 GB的字符串时出现java.lang.OutOfMemoryError: Java heap space
错误。我使用的执行程序内存是6 GB。为了增加用户内存,我甚至将spark.memory.fraction
减少到0.3,但我仍然得到相同的错误。似乎降低该值没有任何影响。我正在使用Spark 1.6.1并使用Spark 1.6核心库进行编译。我在这里做错了吗?
答案 0 :(得分:3)
请参阅SparkConf
Spark Executor OOM:如何在Spark上设置内存参数 一旦应用程序运行下一个最可能的错误,您将看到一个火花执行器上的OOM。 Spark是一个非常强大的工具,用于进行内存计算,但它的功能带有一些锐利的边缘。执行程序OOM的最常见原因是应用程序正在尝试缓存或将过多信息加载到内存中。根据您的使用案例,有几种解决方案:
增加存储分数变量spark.storage.memoryFraction
。这可以在命令行或SparkConf
对象中按上述设置。此变量准确设置将有多少JVM专用于RDD的缓存和存储。您可以将其设置为0到1之间的值,描述执行程序JVM内存的哪些部分将专用于缓存RDD。如果你的工作需要很少的shuffle内存,但会利用大量的缓存RDD来增加这个变量(例如:缓存RDD然后对其执行聚合。)
如果所有其他方法都失败了,您可能只需要为每个工作人员提供额外的ram。
然后通过在命令行或SparkConf对象中设置spark.executor.memory
变量来增加ram应用程序请求的数量。
在你的情况下,某种程度上似乎没有应用记忆分数设置。如评论中所建议,您可以打印所有应用的设置进行交叉检查。
logger.info(sparkContext.getConf.getAll.mkString("\n")
如果未应用,则可以语法设置并尝试查看效果。
val conf = new SparkConf()
.set("spark.memory.fraction", "1")
.set("spark.testing.memory", maxOnHeapExecutionMemory.toString)
...
如test
中所述请仔细阅读this nice post以详细了解
帖子上面的要点是:
您可以在图表上看到3个主要内存区域:
1)保留存储器:系统保留的存储器,其大小为 硬编码
2)用户内存(在Spark 1.6“Java堆” - “保留内存”中)*(1.0 - spark.memory.fraction)
这是分配Spark后剩余的内存池 记忆,完全取决于你喜欢的方式使用它。
用户记忆和它完全取决于你将存储在这里 RAM以及如何,Spark完全没有考虑你在那里做什么 以及你是否尊重这个边界。不尊重这一点 代码中的边界可能会导致OOM错误。3)Spark内存(“Java堆” - “预留内存”)* spark.memory.fraction, - > Spark管理的内存池。进一步 分成
| - >存储内存
| - >执行记忆