1. ホーム
  2. JVM

インタビュアー JDK8のメモリチューニングはどのように行うのですか?

2022-02-23 06:48:41
<パス <ブロッククオート

記事は継続的に更新されています、weiboは"で検索してください。 ワンキャッツ "まずは読んでみてください。
フォローと返信 " 電子書籍 Javaに関する必読の技術書12冊を無料でお届けします。

インタビュアー JDK8のメモリチューニングはどのように行っているのですか?

面接官の誠実な眼差しを見て、私は若く見えるのに、こんなにストレートに魂に訴えかける質問をしたのだと思いました。額の汗を拭きながら......。緊張を少し和らげました。私は面接官にこう言った。

メモリチューニングの前に、JDK8ではメモリ領域がどのように分割されているかを理解する必要があります。

JDK8のメモリ構造

JDK8のメモリ構造は、主に以下のもので構成されています。 プログラムカウンタ (プログラムカウンタレジスタ)は 仮想マシンスタック (Java Virtual Machine Stacks)である。 ローカルメソッドスタック (ネイティブメソッドスタック)、および ヒープ (Javaヒープ)であれば メタスペース (メタスペース)です。

どこ ヒープ がさらに分割され 老後 (オールドジェネレーション)。 ヤングジェネレーション (ヤングジェネレーション)、そのうちの ヤングジェネレーション はさらに分割され エデンゾーン と2つの サバイバーゾーン .

話しながら、ペンを手に取り、紙に絵を描いていく。

図面の後に追記:JDK8のメモリチューニングは、ヒープとメタスペースに着目しています。メモリチューニングによく使われるJVMのパラメータはこれです。

-サーバー

JVMのサーバーモードは、マルチCPUサーバーでのパフォーマンスを向上させることができますが、JDKの64ビット版でのみサポートされているため、この場合、オプションは暗黙の了解となっています。

-Xmx

XX:MaxHeapSizeに相当し、ヒープで割り当てるメモリの最大量を指定します。文字が付加されていない場合、単位はバイトで、1024の倍数でなければならず、2MBより大きく、kまたはKが付加されている場合はKB、mまたはMが付加されている場合はMB、gまたはGが付加されている場合はGとなります。

次の例では、異なる単位を使用して、ヒープで割り当てられるメモリの最大値を1GBに設定しています。

-Xmx1G
-Xmx1024M
-Xmx1048576K
-Xmx1073741824


-Xms

ヒープで確保するメモリの初期値を指定する。文字が付加されていない場合はバイト単位で、1024の倍数かつ1MB以上、kまたはKが付加されている場合はKB単位、mまたはMが付加されている場合はMB単位、gまたはGが付加されている場合はG単位で指定する。 この初期値を設定しない場合、初期値は、ヒープのサイズの合計に設定される。

次の例では、異なる単位を使用して、ヒープで割り当てられた初期値を4GBに設定しています。

-Xms4G
-Xms4096M
-Xms4194304K
-Xms4294967296


実稼働環境では、-Xms と -Xmx は通常同じ値に設定されます。

-Xmn

ヒープに割り当てられた最も若いメモリの初期値と最大値を指定する。文字が付加されていない場合はバイト単位、kまたはKが付加されている場合はKB単位、mまたはMが付加されている場合はMB単位、gまたはGが付加されている場合はG単位で指定する。

ヒープの若い世代の領域は、生まれたばかりのオブジェクトを保持するために使用されます。この領域では、他の領域よりも頻繁にガベージコレクションが実行される。もし、若い世代のメモリが小さすぎる場合は、多くのガベージコレクションが実行されることになる。ヤングジェネレーションが大きすぎる場合、完全なガベージコレクションが完了するまでに長い時間がかかることがあります。 一般に、若い世代のサイズはヒープ全体のサイズの1/2〜1/4の間に保つことが推奨されています。

次の例では、若い世代に割り当てるメモリの初期値と最大値を、異なる単位で2GBに設定しています。

-Xmn2G
-Xmn2048M
-Xmn2097152K
-Xmn2147483648


Xmnオプションで若い世代の初期値と最大値を設定するほか、-XX:NewSizeで若い世代の初期値を、-XX:MaxNewSizeで若い世代の最大値を設定することも可能です。

-XX:NewRatio

オールドエイジとヤングエイジのスペースサイズの比率を指定します。デフォルトは2です。つまり、古い年齢と若い年齢のスペースサイズの比率は2:1で、若い年齢がヒープメモリ全体のサイズの1/3を占めます。次の例では、古い年齢と若い年齢のスペースサイズの比率を1に設定しています。

-XX:NewRatio=1


また、若い世代の割り当てメモリの優先順位は以下のように設定されています。

  1. 優先度高:-XX:NewSize/-XX:MaxNewSize
  2. 中優先度:-Xmn
  3. 優先度低:-XX:NewRatio

-XX:生存率

エデンゾーンとサバイバーゾーンの空間の大きさの比率を指定します。デフォルトは8で、エデン領域とサバイバー領域1つの空間サイズが8:1であることを意味します。Survivor領域が2つあるため、Eden領域は若い世代のメモリサイズの80%を占める。次の例では、Eden領域とSurvivor領域1つの空間サイズの比率を4に設定しています。

-XX:SurvivorRatio=4


-XX:メタスペースサイズ

メタスペースで最初のガベージコレクションが発生するメモリサイズの閾値を指定します。この閾値に達するまでメタスペースのメモリフットプリントが増え続けると、ガベージコレクションが発生します。そのため、この閾値を適切に増加させることで、ガベージコレクションの回数を減らすことができます。デフォルト値はプラットフォームに依存し、通常は約20.8MBです。次の例では、メタスペースで最初にトリガーされるガベージコレクションのメモリサイズを256MBに設定しています。

-XX:MetaspaceSize=256M


一部のパートナー様がこのパラメータを誤解され、無用なご迷惑をおかけしております。もう一度言いますが、-XX:MetaspaceSizeはメタスペースのメモリサイズの初期値ではありません、メタスペースのメモリサイズの初期値ではありません、大事なのは3回言うことです。

-XX:MaxMetaspaceSize

メタスペースに割り当てるメモリの最大量を指定します。デフォルトでは無制限で、システムで利用可能なメモリの量によっては、理論的にはシステム全体のメモリを占有する可能性があります。システム上の他のアプリケーションに影響を与えるこの大失敗を避けるために、そのサイズを適切に設定する必要があります。次の例では、メタスペースに割り当てられるメモリの最大量を512MBに設定しています。

-XX:MaxMetaspaceSize=512M


面接官はにっこり笑って言う。これらのパラメータを使用して、メモリチューニングのサンプルを作成できますか?

もちろんです。

メモリチューニングの例

ガベージコレクションの回数を減らすために、ヒープメモリ空間をできるだけ大きく設定します。サーバーで利用可能なメモリが12GBあると仮定して、まずヒープに割り当てられるメモリの最大値と初期値を8GBに指定します。通常、若い世代のメモリサイズはヒープ全体のサイズの1/2から1/4である必要があるので、若い世代のメモリサイズを3GBに指定します。次にEden領域のサイズとSurvivor領域1個のサイズの比率を4に設定します。メタ空間最初のトリガー ガベージコレクションのメモリサイズの閾値は、一般的に十分な256MBに設定されます。メタスペースに割り当てるメモリの最大値は、極端にメモリを占有しないようにするため、512MBに設定されています。また、JVMをサーバーモードで起動することを明示的に指定する必要がある。

メモリチューニングのためのパラメータは基本的に確定しており、これを用いて one-more-study-0.0.1-SNAPSHOT.jar という名前の jar ファイルが起動されます。

java -server -Xmx8G -Xms8G -Xmn3G -XX:SurvivorRatio=4 -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=512M -jar one-more-study-0.0.1-SNAPSHOT. jar


を実行すると jmap -heap コマンドを実行して、対応する Java プロセスのメモリ割り当てと使用量を確認すると、次のようになります。

Attaching to process ID 31828, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.251-b08

JVM version is 25.251-b08 using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration: #Heap memory configuration
   MinHeapFreeRatio = 0
   MaxHeapFreeRatio = 100
   # Maximum amount of heap memory
   MaxHeapSize = 8589934592 (8192.0MB) 
   # Size of young generation memory
   NewSize = 3221225472 (3072.0MB) 
   # The maximum value of the young generation memory
   MaxNewSize = 3221225472 (3072.0MB) 
   # Size of old generation memory
   OldSize = 5368709120 (5120.0MB) 
    # Ratio of old age to young age space size
    # This setting is not in effect because the Xmn parameter is set
   NewRatio = 2
   # Ratio of the space size of the Eden and one Survivor zones
   SurvivorRatio = 4 
    # The memory size of the first garbage collection trigger for the metaspace
   MetaspaceSize = 268435456 (256.0MB)
    # The maximum amount of metaspace memory
   MaxMetaspaceSize = 536870912 (512.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage: # The usage of the heap
PS Young Generation
Eden Space: # Memory usage of the Eden region
   capacity = 2147483648 (2048.0MB)
   used = 901945720 (860.16MB)
   free = 1245537928 (1187.83MB)
   42.000120505690575% used
From Space: # Survivor's memory usage in the From area
   capacity = 536870912 (512.0MB)
   used = 0 (0.0MB)
   free = 536870912 (512.0MB)
   0.0% used
To Space: # Survivor's To area memory usage
   capacity = 536870912 (512.0MB)
   used = 0 (0.0MB)
   free = 536870912 (512.0MB)
   0.0% used
PS Old Generation # Old generation memory usage
   capacity = 5368709120 (5120.0MB)
   used = 0 (0.0MB)
   free = 5368709120 (5120.0MB)
   0.0% used

12047 interned Strings occupying 1045744 bytes.



彼女の瞳にほのかな憧れが見えた気がする。私は彼女の目にほのかな賞賛を見たような気がする。諺にもあるように、1万テールの金を手に入れるのは簡単だが、自分を知っている人を見つけるのは難しいのだ。

<ブロッククオート

記事は引き続き更新中、weibo検索"。 ワンキャッツ "まずは読んでみてください。
フォローと返信 " 電子書籍 Javaに関する必読の技術書12冊を無料でお届けします。