JVM(XIII):バックエンドのコンパイラの最適化

JVM(XIII):バックエンドのコンパイラの最適化

ではJVM(A):ソースファイルの変換、我々はおよそバイトコードファイルにJavaソースコードに、ジャワのフロントエンドの最適化を導入しました。この記事では、ネイティブマシンコードファイル、およびどのようにバイトコードは、パフォーマンスを向上させるためにコードを最適化する方法について説明します。異なる仮想マシン、バイトコード異なる最適化エンジン、これもデフォルトのHotSpotコンパイラでJITとして使用この例で、あるため。

アーキテクチャ

私たちは皆、それは二つの方法でマシンコードにコードを変換するために知って、そして2つを除くすべての中のHotSpotの使用はアーキテクチャのインタプリタとコンパイラ共存の使用に関連しています。だから、これの目的は何ですか?

まず、コードが実行される必要があるものを、この時点で、ソースコードを対応する翻訳魚は、マシンコードにそれを回すので、起動時の効率を向上させるためにあるためと解釈、大幅に、プログラムを開始の効率を向上させることができることを知っています。

それはマシンに関連付けられたネイティブコードにコンパイルされ、すべてのコードの中間となり、この段階で、いくつかのコンパイラは、行為の予備のコンパイルされたコードになるため、コンパイラの実装の利点は、実装により高い効率を達成することができますまた、より優れた効率を作るの最適化、。

だから、コード実行中に、監視の実装は、前に述べた使用中にホットスポットは、優れた出発効率を得るために、解釈し使用を開始したときに、ホットコードコンパイラ技術ネイティブマシンコードにコンパイルされたホット・コードになります、そしてエグゼクティブケースは、両方の完全な利点を得るために最適化されます。

読者が少し遅いを遅くするのは初めてのため、サーバー上の私のコードを配置するように求められることがあり、私はそれをしないで実行するためのコンパイラを使うのか?

実際には、最初のすべてのコンパイラは、ほかに、プロセスの最適化もあるので、コードを最適化し、より良いの実装に応じた処理の実装を最適化することを確認する必要があるため、ラジカル最適化され、この場合には、方法、通過方法の実施を説明する必要がデ最適化された方法を実行するために状態を説明するために戻ります。

したがって、二つの方法のアーキテクチャの共存は、合理的かつ必要であるため、現在主流の仮想マシンは、主にこのフレームワークを採用します。

タイムコンパイラ

HotSpotの2回のコンパイラ、クライアントコンパイラおよびサーバーのコンパイラと呼ばれる、または単にC1とC2と呼ばれるが、現在の仮想マシンは、一般的に呼ばれるこのモデルを実行するために、時間のコンパイラとインタプリタ直接フィッティングの方法を使用しますある混合モードでは

それは、スケジューリング問題を考慮する限り、必要性2間の協力で、コンパイラの実装が使用するとき、それは、されているので、いつ解釈を使用するには、最大効率を得るために、割合の最適なバランスを得ることができますどのくらい。

ホットスポットはであるコンパイル階層達成するために最適なソリューション戦略を。私たちは、次のようにその本質があると思いました:

  • レベル0:解釈プログラムは、インタプリタがオープンパフォーマンス監視をせず、第一の層を引き起こし。
  • ティア1:必要に応じてネイティブコードへのバイトコードをコンパイルC1コンパイル、、、単純な信頼性の最適化、性能監視に加えてもよいです。
  • ティア2:C2コンパイラは、バイトコードをネイティブコードにコンパイルされますが、それはいくつかの長い最適化を開始し、さらに監視するための情報を最適化するために、いくつかのラジカル措置を講じます。

特定の状況に最適なソリューションを実現する方法は、この層状のコンパイルは:C1より速く、コンパイル速度を取得し、解釈C2とのより良い品質のコンパイルを取得、それはまた、パフォーマンス監視ミッションを増やす必要はありませんが、ドラッグ開始効率。

コンパイルされたオブジェクト

コンパイル処理は時間のかかる作業であるため、そのあまり頻繁に実行されるコードは、より高い増加を得るためにコンパイルされます。それでは、どのコードがそうであるかを判断するコード熱いそれは?

JVMでは、ホットコードが決定された2つの方法があります。

  • ベースサンプリングスタックフレームの上部にコードのピースが頻繁に発生する場合、スタックの定期点検の上部には、コードが高温であると判定されます。
    • 長所:シンプル、速いです。
    • 短所:簡単にブロックされた衝撃検出スレッドを受け取ります。例えば、スレッドがブロックされているので、この方法は、スタックの最上位となっているが、実行回数があまりないという事実は、コードは無理である焦点と判定されます。
  • カウンタに基づいて、各メソッドであるため、カウント数が所定の条件に達した場合、コードブロックがあっても、実行回数をカウントするカウンタを確立するには、ホットコードに記載されています
    • 長所:正確な結果
    • 短所:多くのトラブルを達成、あなたはカウンターを維持する必要があります

頻繁に実行されるコードは、次の2つの方法を持っているので、ホットスポットは、第二のオプションに取り込まれます。

  • 実行の頻繁な方法
  • のコードを頻繁に実施

したがって、ホットスポットは以下の通りである。その実行ロジックを判断するためのカウンタの2種類を確立しました:

メソッド呼び出しカウンタ

メソッドおよびメソッド一貫した裏側を分析するだけコンパイル要求の提出後、カウンタビットの裏面の値を小さくする必要があり、状態が継続することを保証するために、コードを解釈。

カウンターの横にコールバック

クラシックの最適化

そこあまりにも多くのJITコンパイラの最適化技術があり、ここではさらにいくつかの古典的なプレゼンテーション、興味のある読者の残りの部分はあなたがして、およそ別の記事を拡張することができ、それをグーグル、または作成者にメッセージを残すことができます見つけます。

インラインメソッド

連合の方法の中で最も重要なJavaのいくつかの最適化手法の一つである必要があり、その存在の最大の意義は、他の最適化手法のための基盤を提供することです。これは、コードの膨張を行い、そのためにも、最適化のためのより多くの機会を提供します。

表面には、との内側の方法は、単に電話をかけるために、コードをコピーし、それは本当に簡単なだろうか?

我々は唯一の導入、前記のように多型メソッドを呼び出し、非仮想メソッド、コンパイル時に知ることができる方法のバージョンが呼び出されるが、仮想、この方法は、コンパイラ次に、選択することができる複数のバージョンが存在してもよいですメソッドのインライン化、コードのコピーを行う際に?

この問題を解決するために、JVMチームが導入分析型の継承の技術を。次のようにこの技術を実行するためのロジックは次のとおりです。

米国内のプロセスの方法

共通部分式除去

2つの計算における発現は、すべての変数の値がその中に変更されていない場合、それは、共通の部分式と呼ばれます。

栗の場合:

int a = (b*c)*4+(c*b+d)+d

上記の計算コードがb*c二度と変わらないので、それはと略記することができるint a = E * 4 + (E + d) + d、またすることができる代数簡略化のために最適化された最適化:

int a = E * 5 + 2 * d;

排除をチェック配列の境界

Java 语言中为了保持代码的健壮和安全性,在每次数组访问的时候需要判断其是否在 0 ~ length-1 的范围内,如若不然,将抛出异常。这样做有个显而易见的好处是可以提高程序的健壮性,但这对于拥有大量数组访问的程序来说,就是一个灾难了。

因此,如果可以确保数组访问不会越界的情况下,JVM 则可以做出相应的优化,例如可以使用隐式异常处理。栗子如下:

if(object != null){
    return object.value;
}else{
    throw new Exception();
}

在确定如果 object 在大多数情况下不会为空后,可以做出以下优化:

try{
    return object.value;
}catch(segment_fault){
    exception_execute;
    ....
}

这样就可以减少大量的判断开销。

逃逸分析

逃逸分析可以说是目前最前沿的优化技术。其是指当分析对象作用域时,如果一个对象在被定义后,其不会外部方法和线程访问到,那么就可以说明其是不会逃逸的,即其生命周期只有在被定义的块中,因此就可以对其进行优化。

  • 栈上分配,Java 对象大家都知道是分配在堆上的,但通过前面的学习,我们知道栈上的对象在管理时,是十分地影响性能的。因此我们考虑,既然其不会逃逸的话,那么直接将其分配到栈上不是更好吗。这样其可以随着线程的消亡而消亡,减少垃圾收集的压力;
  • 同步消除,如果对象不会逃逸,就别谈线程不安全的访问了,也就不会被多个线程访问,因此没有必要对其进行同步,直接可以把同步消除掉;
  • 标量替换,Java 中的对象分为 标量聚合量 ,其中标量是不能再被拆分的变量,如 int、long 等。而聚合量中最典型的就是对象,现在如果能判断对象不会逃逸,因此结合栈上分配,将其拆分为标量然后分配到栈上是一个很好的优化方式。

前面说了那么多逃逸分析的优点,但目前逃逸分析技术还并不是十分的成熟,其能够带来的优化效果还不好说。

例如下面这种极端情况,JVM 在经过逃逸分析后,发现所有的对象都是可以逃逸出去的,那么就带来的性能消耗就十分的不值了,因为毕竟逃逸分析是一个相对高耗时的过程,耗费了大量的时间和运算资源,结果发现全部白费了。

それでも、私はエスケープ解析が最適化された技術ロードマップでなければならないと考えています。それは最適化されたコードを通過するので、大幅に性能を向上させます。

概要

この記事では、我々はそのコンパイラアーキテクチャ、コードの一部は、ネイティブコードにコンパイルされるに値する判断する方法のアイデア、の積層コンパイル、およびコードを最適化するために取るべき方法を含め、分析のバックエンドの側面をまとめました。

で、深さ、これらの要素を理解することは、私たちは、コードが自分の符号化効率を向上させるために、自分自身に対処する必要があるコンパイラを最適化することができる仕事を分離するのに役立ちます。

いいえ公共iceWangありません

商品番号がじかに、公共の「iceWang」に更新興味の友人は、公開番号を集中することができ、私は知識共有のポイントを参照してください最初の時間は、ありがとうございました!リフィル!

記事のこのシリーズは主に、「綿密なテクニカル分析JavaWebインサイダー」から借りている「Java仮想マシンの深い理解-JVM高度な機能とベストプラクティス。」

おすすめ

転載: www.cnblogs.com/JRookie/p/11431784.html