Spark应用程序-Java.lang.OutOfMemoryError:Java堆空间

Spark应用程序-Java.lang.OutOfMemoryError:Java堆空间,java,apache-spark,jvm,out-of-memory,heap-memory,Java,Apache Spark,Jvm,Out Of Memory,Heap Memory,我使用的是Spark单机版,128G内存,32核。以下是我认为与我的问题相关的设置: spark.storage.memoryFraction 0.35 spark.default.parallelism 50 spark.sql.shuffle.partitions 50 我有一个Spark应用程序,其中有1000个设备的循环。对于每个循环(设备),它准备特征向量,然后调用MLLib的k均值。在循环的第25次到第30次迭代(处理第25次到第30次设备)时,它遇到

我使用的是Spark单机版,128G内存,32核。以下是我认为与我的问题相关的设置:

spark.storage.memoryFraction     0.35
spark.default.parallelism        50
spark.sql.shuffle.partitions     50
我有一个Spark应用程序,其中有1000个设备的循环。对于每个循环(设备),它准备特征向量,然后调用MLLib的k均值。在循环的第25次到第30次迭代(处理第25次到第30次设备)时,它遇到错误“Java.lang.OutOfMemoryError:Java堆空间”

我试着从0.7到0.35进行记忆练习,但没有效果。我还尝试将并行/分区设置为200,但没有成功。JVM选项是“-Xms25G-Xmx25G-XX:MaxPermSize=512m”。我的数据大小只有2G左右

下面是堆栈跟踪:

java.lang.OutOfMemoryError: Java heap space
  at java.util.Arrays.copyOf(Arrays.java:2271)
  at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)
  at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
  at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
  at java.io.ObjectOutputStream$BlockDataOutputStream.write(ObjectOutputStream.java:1841)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1533)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
  at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
  at scala.collection.mutable.HashMap$$anonfun$writeObject$1.apply(HashMap.scala:138)
  at scala.collection.mutable.HashMap$$anonfun$writeObject$1.apply(HashMap.scala:136)
  at scala.collection.mutable.HashTable$class.foreachEntry(HashTable.scala:230)
  at scala.collection.mutable.HashMap.foreachEntry(HashMap.scala:40)
  at scala.collection.mutable.HashTable$class.serializeTo(HashTable.scala:125)
  at scala.collection.mutable.HashMap.serializeTo(HashMap.scala:40)
  at scala.collection.mutable.HashMap.writeObject(HashMap.scala:136)
  at sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)

起初,应用程序看起来不错,但在运行一段时间并处理越来越多的设备后,Java堆逐渐被占用,JVM不会释放内存。如何诊断和修复此类问题

您始终可以使用探查器工具,如。监视内存增长。
希望您使用的是64位JVM,而不是32位JVM。32位进程只能使用2GB内存,因此内存设置基本上没有用处。希望这有帮助,JVM选项不足以配置Spark内存,您还需要设置
Spark.driver.memory
(对于驱动程序,obv)和
Spark.executor.memory
(对于工作人员)。这些默认设置为1gb。了解更多信息。事实上,我劝你读一读,里面有很多东西,了解它以后肯定会有回报。

除了驱动程序和执行器内存之外,我建议你尝试以下选项:-

  • 切换到Kryo序列化-
  • 使用内存和磁盘服务器2进行RDD持久化

  • 另外,如果您能发布代码也很好。

    谢谢您推荐visualVM。我现在正在尝试监视内存使用情况。顺便说一句,我使用的是64位JVM。在我的设置中,我有“spark.driver.memory 16G”和“spark.executor.memory 96G”。实际上,我查阅了Spark配置文档,但仍然无法解决OOM问题。我现在尝试visualVM来看看堆中发生了什么。它试图序列化数据,可能是一个非常大的数据量。我建议您将最大堆大小从25GB增加到100GB。现在尝试堆大小100G。谢谢您的建议。您是否尝试将spark.rdd.compress设置为true?谢谢您的建议!我已经使用了Kryo序列化。由于MEMORY_AND_DISK_SER_2明显比MEMORY_慢,除非我没有其他选择,否则我不愿意使用它。我同意,但建议“MEMORY_AND_DISK_Seru_2”的目的是首先确保您的工作至少完成。这将验证您的逻辑是否正确(尽管未优化),然后我们可以调整它以获得更好的性能,使其完全在内存中执行。我将尝试选项memory\u和\u DISK\u SER\u 2。