JVMチューニング-学習編


概要
会社の江南白衣は重要な業務システムのJVMパラメータ推薦(2016熱冬版)の文章を書いたが、大牛の文章はいつも細かく読む必要がある.この文章は大量のJVMのチューニングパラメータを紹介して、内容も比較的に多くて、本文はただ私自身が理解できるいくつかのパラメータをリストして、しばらく理解できないパラメータは後で自分の実力が家に着くのを待つしかなくて、更にゆっくりと補充します.
パフォーマンスチューニングパラメータ
-XX:AutoBoxCacheMax
JAVAプロセスが開始されると、rt.jarというコアパッケージがロードされます.rt.jarパッケージのIntegerも当然JVMにロードされます.IntegerにはIntegerCacheキャッシュがあります.以下のようにします.
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
}

IntegerCacheには静的コードブロックがあり、JVMはIntegerというクラスをロードするときに静的コードを優先的にロードします.JVMプロセスの起動が完了すると、-128~+127の範囲の数字がキャッシュされ、valueOfメソッドが呼び出されると、この範囲の数字であればそのままキャッシュから取り出されます.この範囲を超えると、新しいIntegerオブジェクトを構築するしかありません.
public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
}

そのため、実際の状況に応じてAutoBoxCacheMaxの値を大文字に設定することができます.例えば、江南の白衣がお勧めします.
-XX:AutoBoxCacheMax=20000

-XX:+AlwaysPreTouch
JAVAプロセスが開始されると、JVMに適切なメモリサイズを指定できますが、これらのメモリオペレーティングシステムはJVMに実際に割り当てられていません.JVMがこれらのメモリにアクセスするのを待ってから、実際に割り当てられます.これにより、次のような問題が発生します.1、GCの时、新生代の対象が古い年代に升格する时、メモリが必要で、この时オペレーティングシステムはやっと本当にメモリを分配して、このようにyoung gcの停止时间を増大します;2、メモリの断片化の問題がある可能性があります.
JVMの起動時に設定できます
-XX:+AlwaysPreTouch

パラメータ、このようにJVMは先にすべての割り当てられたメモリにアクセスして、オペレーティングシステムにメモリを本当にJVMに割り当てさせます.その後のJVMでメモリへのアクセスがスムーズになります.
GCパラメータ
JAVA 1.7用のゴミ収集アルゴリズムはCMSであり,以下に述べるパラメータはCMSに対するものである.
CMSInitiatingOccupancyFraction
以前javaごみ回収アルゴリズムの-CMS(同時タグクリア)を書いたことがありますが、ごみ収集スレッドはアプリケーションのスレッドと並行して動作します.もしごみ収集スレッドが動作していたら、古い世代のメモリが不足したらどうしますか.そのため、事前にCMSを起動してゴミ収集(CMS GC)したほうがいいです.設定
CMSInitiatingOccupancyFraction=75

では、古い年代のスタックスペースの使用率が75%に達するとゴミ回収が開始され、CMSInitiatingOccupancyFractionのデフォルト値は92%で、これは大きすぎます.CMSInitiatingOccupancyFractionパラメータは、次の2つのパラメータとともに使用する必要があります.
-XX:+UseConcMarkSweepGC 
-XX:+UseCMSInitiatingOccupancyOnly

MaxTenuringThreshold
新生代はcopyアルゴリズムを用いてごみ回収を行うもので,参照できる.
JAvaごみ回収アルゴリズムの-copingレプリケーション
デフォルトでは、新生代がyoung gcを15回実行した後、Survivor領域にオブジェクトが存在する場合、これらのオブジェクトをそのまま古い年代に昇進させることができますが、新生代がcopyアルゴリズムを使用するため、Survivor領域が長く生存するオブジェクトがあれば、Survivor領域が生存するオブジェクトが多くなり、これはcopyアルゴリズムの性能に影響し、young gcが停止する時間が長くなります.推奨は6に設定します.
-XX:MaxTenuringThreshold=6

ExplicitGCInvokesConcurrent
NettyのDirectByteBufferクラスなど、システムがスタック外メモリを使用している場合は、スタック外メモリを回収する場合に呼び出す必要があります.
System.gc()

この方法はfull gcを行い、アプリケーション全体が停止し、CMSゴミ収集器を使用する場合は設定できます.
-XX:+ExplicitGCInvokesConcurrent

このパラメータは、full gc->CMS GCから同時収集されるようにSystem.gc()の動作を変更し、中間実行中にstop the worldが必要な段階は一部のみである.
注意:ExplicitGCIInvokesConcurrentが設定されている場合は、DisableExplicitGCパラメータを設定してSystem.gc()を無効にしないでください.
メモリパラメータ
-Xmx, -Xms
この2つは一般的に4つのgを設定しています
NewRatio
GCが一番多いのは新生代のyoung gcですので、新生代全体の占有割合を上げることができますが、半分に設定することをお勧めします.young gcはできるだけ避けることをお勧めします.
-XX:NewRatio=1