web-dev-qa-db-ja.com

Sparkアプリケーション-Java.lang.OutOfMemoryError:Javaヒープスペース

私はSparkスタンドアロンのシングルマシン、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によって解放されません。診断と修正の方法そのような問題?

7
wdz

ドライバとエグゼキュータのメモリとは別に、次のオプションを試すことをお勧めします。

  1. Kryoシリアル化に切り替える- http://spark.Apache.org/docs/latest/tuning.html#data-serialization
  2. RDDの永続性にはMEMORY_AND_DISK_SER_2を使用します。

また、コードを投稿していただければ幸いです。

5
Sumit

visualVM のようなプロファイラーツールをいつでも使用できます。メモリの増加を監視します。うまくいけば、32ビットJVMではなく64ビットJVMを使用しています。 32ビットプロセスは2GBのメモリしか使用できないため、メモリ設定は基本的に役に立ちません。お役に立てれば

4
R Sawant

JVMオプションは、Sparkメモリの構成には不十分です。また、spark.driver.memory(ドライバーの場合)およびspark.executor.memory(ワーカーの場合)も設定する必要があります。これらは設定されています。デフォルトで1GBまで。 この完全なガイドを参照 詳細については、実際に読んでおくことをお勧めします。そこには非常に多くのものがあり、それに精通することは間違いなく後で報われるでしょう。

2
mehmetminanc