繁体   English   中英

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

[英]Spark applicaition - Java.lang.OutOfMemoryError: Java heap space

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

spark.storage.memoryFraction     0.35
spark.default.parallelism        50
spark.sql.shuffle.partitions     50

我有一个Spark应用程序,其中有一个1000个设备的循环。 对于每个循环(设备),它准备特征向量,然后调用MLLib的k-Means。 在循环的第25到第30次迭代(处理第25到第30个设备)时,它会遇到“Java.lang.OutOfMemoryError:Java堆空间”的错误。

我尝试了从0.7到0.35的memoryFraction,但它没有帮助。 我也尝试并行/分区到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不会释放内存。 如何诊断和解决这样的问题?

除了Driver和Executor内存之外,建议尝试以下选项: -

  1. 切换到Kryo序列化 - http://spark.apache.org/docs/latest/tuning.html#data-serialization
  2. 使用MEMORY_AND_DISK_SER_2进行RDD持久化。

此外,如果您可以发布代码将是好的。

您始终可以使用visualVM等分析器工具。 监控内存增长。 希望您使用的是64位JVM而不是32位JVM。 32位进程只能使用2GB内存,因此内存设置基本上没用。 希望这可以帮助

JVM选项不足以配置Spark内存,还需要设置spark.driver.memory (对于driver, spark.executor.memory 。)和spark.executor.memory (对于worker)。 这些默认设置为1GB。 有关详细信息, 请参阅此完整指南 实际上,我恳请你阅读它,那里有很多东西,熟悉它肯定会在以后得到回报。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM