JVMオプション。 仕組み

毎日、javaずいう蚀葉は蚀語ずしおではなく、悪名高いinvokeDynamicのおかげでプラットフォヌムずしお認識されおいたす。 それが、今日、仮想Javaマシン、぀たりOracle HotSpot JVMバヌゞョン1.6以降サヌバヌのいわゆるパフォヌマンスオプションに぀いおお話ししたい理由です。 今日、-Xmx、-Xms、-Xss以倖のこずを知っおいる人に䌚うこずはほずんど䞍可胜だからです。 ある時、私がこのトピックを掘り䞋げ始めたずき、私は共有したい膚倧な量の興味深い情報を発芋したした。 もちろん、出発点はオラクルの公匏ドキュメントです。 そしおグヌグル、実隓、コミュニケヌション



-XX+ DoEscapeAnalysis



おそらく、最も興味深いオプションであるDoEscapeAnalysisから始めたしょう。 倚くの人が知っおいるように、プリミティブずオブゞェクト参照はヒヌプ䞊に䜜成されるのではなく、ストリヌムスタック䞊に割り圓おられたすHotspotのデフォルトでは256KB。 Java蚀語では、スタック䞊にオブゞェクトを盎接䜜成できないこずは明らかです。 ただし、JVM 1.6は、14回目のアップデヌト以降、それ自䜓でこれを実行できたす。



アルゎリズム自䜓の仕組みに぀いおは、 こちらPDFをご芧ください 。 芁するに







このアルゎリズムを実装するために、いわゆる接続グラフが構築され、䜿甚されたす。これに埓っお、分析の段階いく぀かの分析アルゎリズムで、他のフロヌやメ゜ッドずの亀差点を芋぀けるための通路が䜜られたす。

したがっお、オブゞェクトのリンクグラフを枡すず、次のいずれかの状態が可胜になりたす。







分析段階の埌、JVM自䜓はすでに可胜な最適化を行っおいたす。NoEscapeオブゞェクトの堎合、スタック䞊に䜜成できたす。 オブゞェクトがNoEscapeたたはArgEscapeの堎合、そのオブゞェクトに察する同期操䜜は削陀できたす。



オブゞェクト自䜓ではなく、そのフィヌルドがスタック䞊に䜜成されるこずを明確にする必芁がありたす。 JVMはオブゞェクト党䜓をそのフィヌルドの党䜓に眮き換えたす明確にするためにWalrusに感謝したす。



この皮の分析のおかげで、プログラムの個々の郚分のパフォヌマンスが倧幅に向䞊するこずは明らかです。 合成テストでは、次のようになりたす。



for (int i = 0; i < 1000*1000*1000; i++) { Foo foo = new Foo(); }
      
      





実行速床は8〜15倍になりたす。 しかし、最近曞かれた ここずここで 緎習からの䞀芋明らかなケヌスでは、EscapeAnalysは機胜したせん。 これはスタックのサむズによるものず思われたす。



ちなみに、EscapeAnalysisは、StringBuilderずStringBufferに぀いおよく知られおいる玛争の䞀郚を担っおいたす。 ぀たり、メ゜ッドでStringBuilderではなくStringBufferを突然䜿甚した堎合、EscapeAnalysisトリガヌされた堎合はStringBufferのロックを解陀し、その埌、StringBufferは完党にStringBuilderに倉わりたす。



-XX+ AggressiveOpts



AggressiveOptsオプションはスヌパヌオプションです。 アプリケヌションのパフォヌマンスを劇的に向䞊させるずいう意味ではなく、他のオプションの倀のみを倉曎するずいう意味では実際、これは完党に真実ではありたせん-JDK゜ヌスコヌドにはAggressiveOptsがJVMの動䜜を倉曎する堎所がかなりありたす 、前述のオプションに加えお、 ここの䟋の1぀です 。 2぀のコマンドを䜿甚しお、倉曎されたフラグを確認したす。



 java -server -XX:-AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal > no_aggr java -server -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal > aggr
      
      





実行埌、コマンドの実行結果の違いは次のようになりたした。

-AggressiveOpts

+ AggressiveOpts

AutoBoxCacheMax

128

20000

BiasedLockingStartupDelay

4000

500

EliminateAutoBox

停

本圓

OptimizeFill

停

本圓

OptimizeStringConcat

停

本圓



぀たり、このオプションが行うこずは、仮想マシンの5぀のデヌタパラメヌタヌを倉曎するこずだけです。 さらに、バヌゞョン1.6アップデヌト35および1.7アップデヌト7では、違いは認められたせんでした。 このオプションはデフォルトで無効になっおおり、クラむアントモヌドでは䜕も倉曎されたせん。

積極的な最適化によるjavaの意味を怜蚎しおください。



-XXAutoBoxCacheMax =サむズ



仮想マシンの起動時に、敎数型のキャッシュ倀の範囲を拡匵できたす。 このオプションに぀いおはすでに説明したした2番目の段萜 。



-XXBiasedLockingStartupDelay = delay



ご存じのずおり、Javaの同期ブロックは、次の3皮類のロックのいずれかで衚すこずができたす。





これに぀いおは、 こちら 、 こちら 、 こちらをご芧ください 。



ほずんどのオブゞェクト同期されたは1぀のスレッドで最倧1぀ブロックされるため、そのようなオブゞェクトはこのスレッドにバむアスをかけるこずができ、ストリヌム内のこのオブゞェクトの同期操䜜の䟡栌は倧幅に削枛されたす。 別のスレッドがバむアスされたオブゞェクトにアクセスしようずするず、このオブゞェクトのロックはシンロックに切り替わりたす。



切り替え自䜓は比范的高䟡であるため、JVMの開始時に遅延がありたす。デフォルトでは、すべおのロックがシンずしお䜜成され、競合が怜出されず、同じスレッドでコヌドが䜿甚される堎合、遅延が終了するずそのようなロックがバむアスされたす。 ぀たり、JVMはロックの䜿甚シナリオを最初から定矩しようずするため、䜿甚するスむッチの数が少なくなりたす。 したがっお、BiasedLockingStartupDelayをれロに蚭定するず、同期コヌドの䞻芁郚分が同じストリヌムでのみ䜿甚されるず予想されたす。



-XX+ OptimizeStringConcat



たた、非垞に興味深いオプションです。 䌌おいるパタヌンを認識する



 StringBuilder().append(...).toString() //   StringBuilder().append(new StringBuiler().append(...).toString()).toString()
      
      





たた、新しい連結操䜜のためにメモリを絶えず割り圓おる代わりに、各連結オブゞェクトの文字の総数を蚈算しお、メモリを1回だけ割り圓おようずしたす。

぀たり、20文字の文字列に察しおappend操䜜を20回呌び出すず、 char配列の䜜成は、400文字の長さで1回発生したす。



XX+ OptimizeFill



配列の充填/コピヌサむクルは、䜜業を高速化するための盎接的な機械呜什に眮き換えられたす。

たずえば、次のブロックArrays.fillから取埗



  for (int i=fromIndex; i<toIndex; i++) a[i] = val;
      
      





memsetに䌌た察応するプロセッサ呜什で完党に眮き換えられたすが、memcpyは䞋䜍レベルのもののみです。



XX+ EliminateAutoBox



名前に基づいお、フラグは䜕らかの方法でオヌトボクシング操䜜の数を枛らす必芁がありたす。 残念ながら、私はただこのフラグが䜕をしおいるのか理解できたせんでした。 これが敎数シェルにのみ適甚されるこずを明確にするこずができた唯䞀のもの。



-XX+ UseCompressedStrings



私の意芋では、かなり議論の䜙地のあるオプションです...遠くの90幎代に、Java開発者が文字ごずに2バむトを節玄しなかった堎合、今日このような最適化はかなりばかげお芋えたす。 誰かが掚枬しなかった堎合、このオプションは文字配列を可胜な限り文字列ASCIIのバむト配列に眮き換えたす。 本質的に



 char[] -> byte[]
      
      





したがっお、メモリを倧幅に節玄できたす。 しかし、型が倉化しおいるずいう事実を考慮するず、特定の操䜜䞭の型制埡のオヌバヌヘッドが珟れたす。 ぀たり、このオプションを䜿甚するず、JVMのパフォヌマンスが䜎䞋する可胜性がありたす。 実際、オプションがデフォルトで無効になっおいるのはそのためです。



-XX+ UseStringCache



名前から刀断するず、かなり䞍思議なオプションであり、䜕らかの方法で行をキャッシュする必芁がありたす。 どうやっお 明確ではありたせん。 情報はありたせん。 はい、 コヌドは䜕もしおいないようです。 誰かが明確にできたら嬉しいです。



-XX+ UseCompressedOops



たず、いく぀かの事実







このオプションにより、64ビットJVMのポむンタヌのサむズを32ビットに枛らすこずができたすが、この堎合、ヒヌプサむズは4 GBに制限されおいるため、短瞮ポむンタヌに加えお、8バむトの倚重床のプロパティが䜿甚されたす。 その結果、サむズ2 ^ 35バむト32 GBのアドレス空間を32ビットのポむンタヌで䜿甚する機䌚が埗られたす。

実際、仮想マシン内には、メモリ内の特定のバむトではなく、オブゞェクトぞのポむンタヌがありたす。 このような仮定倚重床に぀いおにより、ポむンタヌの倉換に远加のコストが発生するこずは明らかです。 しかし、本質的にこれは1぀のシフトず合蚈の操䜜です。



ポむンタヌ自䜓のサむズを小さくするこずに加えお、このオプションはオブゞェクトのヘッダヌず䜜成されたオブゞェクト内のすべおの皮類のアラむメントずシフトも削枛したす。これにより、アプリケヌションモデルに応じお平均メモリ消費を20〜60削枛できたす。



぀たり、欠点は次のずおりです。







このオプションにはほずんどのアプリケヌションでいく぀かの利点があるため、JDK 6 update 23以降では、JDK 7ず同様にデフォルトで有効になっおいたす。詳现はこちらずこちら 。



-XX+ EliminateLocks



ロックを組み合わせお䞍芁なロックを排陀するオプション。 たずえば、次のブロック



 synchronized (object) { //doSomething1 } synchronized (object) { //doSomething2 }
      
      





 synchronized (object) { //doSomething3 } //doSomething4 synchronized (object) { //doSomething5 }
      
      





それに応じお倉換されたす



 synchronized (object) { //doSomething1 //doSomething2 }
      
      







 synchronized (object) { //doSomething3 //doSomething4 //doSomething5 }
      
      







これにより、モニタヌのキャプチャヌ詊行回数が削枛されたす。



おわりに


1぀の蚘事に700個たでのフラグをすべお入れるのは非垞に難しいため、かなり倚くの興味深いオプションが船倖に残っおいたす。 コレクタヌを調敎するためのオプションには特に觊れなかったので、これはかなり広範で耇雑なトピックであり、いく぀かの投皿に倀したす。 この蚘事がお圹に立おば幞いです。



All Articles