私は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によって解放されません。診断と修正の方法そのような問題?
ドライバとエグゼキュータのメモリとは別に、次のオプションを試すことをお勧めします。
また、コードを投稿していただければ幸いです。
visualVM のようなプロファイラーツールをいつでも使用できます。メモリの増加を監視します。うまくいけば、32ビットJVMではなく64ビットJVMを使用しています。 32ビットプロセスは2GBのメモリしか使用できないため、メモリ設定は基本的に役に立ちません。お役に立てれば
JVMオプションは、Sparkメモリの構成には不十分です。また、spark.driver.memory
(ドライバーの場合)およびspark.executor.memory
(ワーカーの場合)も設定する必要があります。これらは設定されています。デフォルトで1GBまで。 この完全なガイドを参照 詳細については、実際に読んでおくことをお勧めします。そこには非常に多くのものがあり、それに精通することは間違いなく後で報われるでしょう。