私の連絡先情報
郵便メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Spring Boot プログラムの JVM パラメータ設定形式 (Tomcat の起動は bin ディレクトリの catalina.sh ファイルに直接追加されます):
java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -jar microservice-eureka-server.jar
結論は:
-Xss 設定が小さいほど、カウント値は小さくなります。これは、スレッド スタックに割り当てられるスタック フレームの数が少なくなりますが、JVM 全体として開くことができるスレッドの数は多くなります。
-Xss: 各スレッドのスタック サイズ、デフォルトは 1M
-Xms: ヒープの初期使用可能サイズを設定します。デフォルトは物理メモリの 1/64 です。
-Xmx: 使用可能なヒープの最大サイズを設定します。デフォルトは物理メモリの 1/4 です。
-Xmn: 新世代のサイズ
-XX:NewRatio: デフォルトの 2 は、新しい世代が古い世代の 1/2 とヒープ メモリ全体の 1/3 を占めることを意味します。
-XX:SurvivorRatio: デフォルトの 8 は、Survivor 領域が Eden メモリの 1/8、つまり新世代メモリの 1/10 を占めることを意味します。
メタスペースに関しては、-XX:MetaspaceSize=N と -XX:MaxMetaspaceSize=N という 2 つの JVM パラメータがあります。
-XX: MaxMetaspaceSize: 最大メタスペース サイズを設定します。デフォルトは -1 です。これは、制限がないこと、またはローカル メモリ サイズによってのみ制限されることを意味します。
-XX: MetaspaceSize: Fullgc をトリガーするメタスペースの初期しきい値をバイト単位で指定します (メタスペースに固定の初期サイズはありません)。この値に達すると、タイプのアンロードに対してフル gc がトリガーされます。コレクターはこの値を調整します。大量のスペースが解放される場合は値を適切に減らし、少量のスペースが解放される場合は -XX:MaxMetaspaceSize (設定されている場合) を超えないように値を適切に増やします。これは、以前の jdk バージョンの -XX:PermSize パラメーターとは異なる意味を持ちます。 -XX:PermSize は、永続世代の初期容量を表します。
メタスペースのサイズ変更にはフル GC が必要なため、これは非常にコストのかかる操作です。アプリケーションの起動時に大量のフル GC が発生する場合、通常は永続世代またはメタスペースのサイズ変更が原因です。 JVM パラメータで MetaspaceSize と MaxMetaspaceSize を同じ値に設定し、8G 物理メモリを搭載したマシンの場合は通常、両方の値を 256M に設定することをお勧めします。
HotSpot 仮想マシンでは、メモリに格納されているオブジェクトのレイアウトは、オブジェクト ヘッダー (Header)、インスタンス データ (Instance Data)、および位置合わせパディング (Padding) の 3 つの領域に分割できます。 HotSpot 仮想マシンのオブジェクト ヘッダーには 2 つの情報が含まれています。最初の部分は、ハッシュ コード (HashCode)、GC 生成経過時間、ロック ステータス フラグ、スレッドが保持するロックなど、オブジェクト自体の実行時データを保存するために使用されます。 、偏ったスレッドID、Favorタイムスタンプなど。オブジェクト ヘッダーの他の部分はタイプ ポインターで、これはオブジェクトのクラス メタデータへのポインターです。仮想マシンはこのポインターを使用して、オブジェクトがどのクラスのインスタンスであるかを判断します。
1. 64 ビット プラットフォーム上の HotSpot で 32 ビット ポインターを使用すると (実際のストレージは 64 ビットを使用します)、メイン メモリとキャッシュの間でデータを移動するためにより大きなポインターを使用すると、同時により多くの帯域幅が使用されます。やがて、GC にも大きなプレッシャーがかかることになる
2. 64 ビット プラットフォームでのメモリ消費を削減するために、ポインタ圧縮機能を有効にします。
3. jvm では、32 ビット アドレスは最大 4G のメモリ (2 の 32 乗) をサポートします。オブジェクト ポインタをヒープ メモリに格納するときに圧縮およびエンコードし、取得後にデコードすることで最適化できます。 CPU レジスターに出力されます (オブジェクト ポインターはヒープ内にあります。これは 32 ビット、レジスター内に 35 ビット、2 の 35 乗 = 32G) を使用して、JVM がより大きなメモリ構成 (32G 以下) をサポートできるようにします。 32ビットアドレスのみ
4. ヒープ メモリが 4G 未満の場合、ポインタ圧縮を有効にする必要はありません。jvm は上位 32 ビット アドレスを直接削除します。つまり、下位仮想アドレス空間が使用されます。
5. ヒープ メモリが 32G を超えると、圧縮ポインタが無効になり、64 ビット (つまり 8 バイト) で Java オブジェクトをアドレス指定することになります。これにより、1 の問題が発生するため、使用しない方がよいでしょう。ヒープ メモリが 32G を超える。
この場合、JVM はエスケープ解析パラメーター (-XX:+DoEscapeAnaracy) をオンにすることでオブジェクトのメモリ割り当て位置を最適化し、最初にスカラー置換 (スタック上の割り当て) によってオブジェクトがスタックに割り当てられるようにします。 JDK7 以降、分析はデフォルトでオンになります。必要に応じてパラメータ (-XX:-DoEscapeAnalysis) を使用してオフにします。
スカラー置換: エスケープ分析によって、オブジェクトが外部からアクセスされず、オブジェクトをさらに分解できると判断された場合、JVM はオブジェクトを作成しませんが、オブジェクトのメンバー変数をこのメソッドで使用される複数のメンバー変数に分解し、これらの代替メンバー変数は、スタック フレームまたはレジスタ上にスペースを割り当てます。これにより、大きな連続スペースがないためにオブジェクトに対するメモリ割り当てが不足することがなくなります。スカラー置換パラメータ (-XX:+EliminateAllocations) を有効にします。これは、JDK7 以降はデフォルトで有効になります。
スカラー量と集合量: スカラーはそれ以上分解できない量であり、JAVA の基本データ型はスカラー (int、long、その他の基本データ型や参照型など) です。スカラーの逆です。はさらに分解できる量であり、この量を重合量といいます。 JAVA では、オブジェクトはさらに分解できる集合体です。
ラージ オブジェクトは、大量の連続メモリ スペースを必要とするオブジェクト (文字列や配列など) です。 JVM パラメータ -XX:PretenureSizeThreshold は、大きなオブジェクトのサイズを設定できます。オブジェクトが設定されたサイズを超えると、オブジェクトは直接古い世代に入り、若い世代には入りません。このパラメータは、Serial および ParNew の 2 つのコレクターでのみ有効です。
たとえば、JVM パラメータを次のように設定します。 -XX:PretenureSizeThreshold=1000000 (単位はバイト) -XX:+UseSerialGC 上記の最初のプログラムを実行すると、ラージ オブジェクトが古い世代に直接入ることがわかります。
なぜこのようにしなければならないのでしょうか?
大きなオブジェクトにメモリを割り当てる際のコピー操作を回避し、効率を低下させるため。
オブジェクトが現在配置されている Survivor 領域 (領域の 1 つ、オブジェクトが配置されている s 領域) で、オブジェクトのバッチの合計サイズが、この Survivor 領域のメモリ サイズ (-XX) の 50% を超えています。 :TargetSurvivorRatio を指定できます)、この時点で、このオブジェクトのバッチの最大存続期間に等しいオブジェクトは、直接古い存続期間に入ることができます。たとえば、Survivor エリアにオブジェクトのバッチがあります。年齢 1 + 年齢 2 + 年齢 n の複数の年齢オブジェクトの合計が Survivor 領域の 50% を超える この時点で、年齢 n (両端を含む) 以上のすべてのオブジェクトが古い世代に入れられます。このルールは、実際には、長期間存続する可能性のあるオブジェクトができるだけ早く古い時代に突入することを望んでいます。オブジェクトの動的な年齢判断メカニズムは、通常、マイナー gc の後にトリガーされます。
若い世代の各マイナー gc の前に、JVM は古い世代の残りの空き領域を計算します。
使用可能なスペースが、若い世代のすべての既存オブジェクト (ガベージ オブジェクトを含む) のサイズの合計より小さい場合
パラメータ「-XX:-HandlePromotionFailure」(jdk1.8ではデフォルトで設定されている)が設定されているかどうかを確認します。
このパラメータが存在する場合、古い世代で使用可能なメモリ サイズが、以前の各マイナー gc の後に古い世代に入ったオブジェクトの平均サイズよりも大きいかどうかがチェックされます。
前のステップの結果が小さい場合、または前述のパラメーターが設定されていない場合は、完全な gc がトリガーされ、新しい世代を保存するのに十分なスペースがまだない場合は、古い世代と若い世代が一緒に収集されます。オブジェクトをリサイクルすると、「OOM」が発生します。
もちろん、マイナー gc の後に古い世代に移動する必要がある残りのオブジェクトのサイズが古い世代の利用可能なスペースより大きい場合は、フル gc の後にフル gc もトリガーされます。マイナー gc の後でも、存続するオブジェクトのためのスペースがまだなく、「OOM」も発生します。
Tomcat のいくつかのメインクラスローダー:
commonLoader: Tomcat の最も基本的なクラス ローダー。読み込みパス内のクラスには、Tomcat コンテナ自体と各 Web アプリからアクセスできます。
catalinaLoader: Tomcat コンテナのプライベート クラス ローダー。読み込みパス内のクラスは Web アプリには表示されません。
sharedLoader: 各 Web アプリによって共有されるクラス ローダー。読み込みパス内のクラスはすべての Web アプリに表示されますが、Tomcat コンテナーには表示されません。
WebappClassLoader: 各 Web アプリのプライベート クラス ローダー。読み込みパス内のクラスは、war パッケージ内の関連クラスの読み込みなど、現在の Web アプリにのみ表示されます。各 war パッケージ アプリケーションには、異なる war パッケージなどの相互分離を実現するための独自の WebappClassLoader があります。アプリケーションでは、実装がそれぞれのスプリング バージョンをロードできるように、さまざまなスプリング バージョンが導入されます。