こんにちは、私が学ぶことができるかどうか2つの質問?
- Scala または Java でヒープ領域が不足する原因として考えられるものは何ですか?
- それを回避するためのベストプラクティスはありますか?
プロセスを開始するJava
と、デフォルトの maxHeapMemory が設定されます。これは、そのプロセスで使用できる最大ヒープ メモリです。コマンドライン引数を渡してそれを増やすことができますが、アプリケーションのメモリ使用量によっては、それでも十分でない場合があります。メモリ リークは、メモリを消費する (ガベージ コレクションのためにメモリを解放しない) 可能性がある別の問題であり、メモリ不足の問題を引き起こす可能性があります。最初に割り当てられるヒープ メモリと最大許容ヒープ メモリの設定は、アプリケーションとそのメモリ使用量によって異なります。そのため、アプリケーションを (メモリ使用量について) 判断、テスト、およびプロファイリングできます。
そもそもヒープメモリに注意する必要があります。一方、アプリケーションでメモリリークが発生している可能性があります。JVMのガベージコレクタを支援できる1つの方法は、参照を無効にすることです。この質問を見てみてくださいJavaメモリ管理を理解する
コントロールパネル>Java>Javaタブ>表示>Javaランタイム環境>に移動して、maxHeapmemoryサイズを割り当てることができます。
要件に応じたAssisgnRunTimeパラメータサイズ例:-Xmx4000m
Scalaに固有のこの質問についてはあまりありません。これは、JVMに関する質問にすぎません。重要なプログラム(ScalaまたはJava)がデフォルトのJVMヒープ制限を超えることは非常に一般的です。
Scalaに固有なのは、すべての関数リテラルと名前によるパラメーターが別々のクラスにコンパイルされるという事実です。関数型プログラミングで強調されているように、関数型リテラルを非常に簡単に使用できるため、Scalaで関数リテラルを作成しているときに気付かないのは非常に簡単です。
したがって、大規模なScalaプログラムでは、これにより、クラスがロードされるPerm-Genスペースが使い果たされることがあります(ユーザー定義クラスのインスタンスが割り当てられる「通常の」ヒープスペースとは対照的です)。JVMには、PermGenサイズを設定するための個別のオプションがあります。「ストック」OracleJVMでは、それは-XX:MaxPermSize=###u
(キロ、メガ、ギガバイトu
の単位文字です)。k
m
g
使用範囲内でオブジェクトを定義すると、多くのメモリ管理を行う必要が大幅に減り、コーディング方法が簡素化されます。
経験則-ローカルオブジェクトは通常、グローバルオブジェクトよりも優れたアイデアです。
class AddThem{
private int sumGlobal = 0; //Usually bad idea for long lived processes
public int addThem(int a, int b){
int sumLocal;
sumLocal = a + b
return sumLocal;
}
}
これは単純化しすぎるかもしれませんが、sumGlobalがオブジェクトのコレクションである場合、それらはAddThemのインスタンスがガベージコレクションされるまでメモリに残ります。sumLocalは別の運命をたどり、そのような状況に適しています。
1) ヒープ メモリの最大量。ソリューション:
-Xmx // maximal amount of heap memory parameter
-d32 // 32-bit VM
2) ヒープ メモリの永続世代空間。解決:
-XX:MaxPermSize
3) メモリ リーク。ソリューション:
jVisualVM
(../java/bin/jvisualvm )を使用したプロファイリングFindBugs
ツールまたは類似のツール4)System.gc
実行するガベージ コレクターを提案します。
Runtime.freeMemory
、Runtime.maxMemory
およびを介してメモリ消費を監視することで OutOfMemoryError を処理し、アプリケーションでメモリ消費の要求が少ないモードでの切り替えと同等にRuntime.totalMemory
実行するSystem.gc
ことができます (たとえば、データをディスクまたはデータベースにスワップします)。重要な決定 (私の使用例では) は、メモリが少ない場合に、特定のスレッドに対して System.gc を時間間隔ごとに 1 回しか実行しない関数を実装することでした。
もちろん、システムはそれ自体で簡単にスワップできますが、遅くなります。また、通常、1 台のマシンで複数の VM が運用されています。