OutofMemoryError 使用 sbt 程序集创建胖 jar

Posted

技术标签:

【中文标题】OutofMemoryError 使用 sbt 程序集创建胖 jar【英文标题】:OutofMemoryErrory creating fat jar with sbt assembly 【发布时间】:2015-09-03 09:44:52 【问题描述】:

我们正在尝试制作一个包含一个小的 scala 源文件和大量依赖项的 fat jar 文件(使用 spark 和 cassandra 的简单 mapreduce 示例):

import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import com.datastax.spark.connector._
import org.apache.spark.SparkConf

object VMProcessProject 

    def main(args: Array[String]) 
        val conf = new SparkConf()
            .set("spark.cassandra.connection.host", "127.0.0.1")
             .set("spark.executor.extraClassPath", "C:\\Users\\SNCUser\\dataquest\\ScalaProjects\\lib\\spark-cassandra-connector-assembly-1.3.0-M2-SNAPSHOT.jar")
        println("got config")
        val sc = new SparkContext("spark://US-L15-0027:7077", "test", conf)
        println("Got spark context")

        val rdd = sc.cassandraTable("test_ks", "test_col")

        println("Got RDDs")

        println(rdd.count())

        val newRDD = rdd.map(x => 1)
        val count1 = newRDD.reduce((x, y) => x + y)

    

我们没有 build.sbt 文件,而是将 jars 放入 lib 文件夹和 src/main/scala 目录中的源文件并使用 sbt run 运行。我们的 assembly.sbt 文件如下所示:

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.13.0")

当我们运行 sbt 程序集时,我们会收到以下错误消息:

...
java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: java heap space
    at java.util.concurrent...

我们不确定如何更改 jvm 设置以增加内存,因为我们使用 sbt 程序集来制作 jar。此外,如果我们编写代码或构建项目的方式出现严重错误,这也会对我们有很大帮助;尝试建立一个基本的 spark 程序有很多令人头疼的问题!

【问题讨论】:

【参考方案1】:

sbt 本质上是一个 java 进程。您可以尝试针对 OutOfMemory 问题调整 sbt 运行时堆大小。

对于 0.13.x,sbt 使用的默认内存选项是

-Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -XX:MaxPermSize=256m

你可以通过做类似的事情来扩大堆大小

sbt -J-Xms2048m -J-Xmx2048m assembly

【讨论】:

使用命令行参数引发错误:[错误] 不是有效的命令:J-Xmx2048m [错误] 不是有效的项目 ID:J-Xmx2048m [错误] 预期的“:”(如果选择a configuration) [error] Not a valid key: J-Xmx2048m [error] J-Xmx2048m 它解决了我的内存问题,但我得到另一个错误“在 GZIPInputStream 中包装 InputStream: java.io.EOFException” @Humayoo:解决方案是什么?我在这里遇到了与 sbt 0.13.15 相同的“不是有效命令”问题【参考方案2】:

我将 spark 作为一个非托管依赖项(将 jar 文件放在 lib 文件夹中),它使用了大量内存,因为它是一个巨大的 jar。

相反,我创建了一个 build.sbt 文件,其中包含 spark 作为提供的非托管依赖项。 其次,我创建了值为-Xms256m -Xmx4g 的环境变量JAVA_OPTS,它将最小堆大小设置为256 MB,同时允许堆增长到最大4 GB。这两个组合使我可以使用sbt assembly创建一个jar文件

有关提供的依赖项的更多信息:

https://github.com/sbt/sbt-assembly

【讨论】:

【参考方案3】:

我以前遇到过这个问题。对于我的环境,设置 Java_ops 不起作用。 我使用下面的命令,它可以工作。

    设置 SBT_OPTS="-Xmx4G" sbt 汇编

没有内存不足的问题。

【讨论】:

它对我有用。谢谢!【参考方案4】:

这对我有用:

sbt -mem 2000 "set test in assembly := " assembly

【讨论】:

以上是关于OutofMemoryError 使用 sbt 程序集创建胖 jar的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的应用程序使用播放框架获取 OutOfMemoryError 元空间?

在 IntelliJ 中从 sbt 控制台设置 JVM 堆大小

使用 sbt.version 1.2.8 发布到 nexus 的 Sbt 插件无法由使用 sbt.version >1.2.8 的 sbt 项目解决

在“sbt-native-packager”脚本中使用除“sbt run”之外的其他 sbt 命令。例如:“sbt flywayMigrate”

如何在 sbt-plugin 中使用 sbt-assembly?

如何在 sbt 项目中使用 sbt 插件作为库依赖项?