Javaのアーキテクチャの道 - (11)JVMおよびヒープオブジェクト

  最後のブログは、私たちは、JVMランタイムメモリモデル、ヒープ、スタック、プログラムカウンタ、およびネイティブメソッドは、要素のスペースをスタックと述べました。私たちは、メインヒープとスタックは、スタック、それぞれ、若い世代と古い時代をもう一度それを言うと、私たちは、ヒープは、オブジェクトを格納するために使用されていることを知っても、一般的に流れていると言います。しかし、具体的なヒープは、それのオブジェクトを格納する方法ですか?あなたはそれにオブジェクトを配置することができた場合、古いです。今、私が見て。

  

 

 

 デフォルトの設定がある場合は、一般的なケースです。私は、我々はそれはおそらく400M、200Mは、私たち若い世代が、その後、エデン地域アカウントの若い世代は8/10 160Mの200Mで、新しいオブジェクトが、この中で一般的にされていますので、古い600Mのメモリヒープサイズを設定すると仮定します私は一般的なああを意味します。600Mは、すなわち、それぞれが20Mを占め領域からとに、後で詳細に説明した本が使用され、領域がサバイバー40Mを占有、各オブジェクトがこの領域に配置され、マイナーGCを終えました。

  私は時々、オブジェクトはので、私は特に若い世代に配置されて何が起こるかを分析し、それらは古い時代に置かれたときに、若い世代ではない、と述べました。

1、後にマイナーGC、サバイバー対象領域フィットを生き残りました。

パブリック クラスメイン{
     公共 静的 ボイドメイン(文字列[]引数){
         バイト[] BT1。
        BT1 = 新しい バイト [60000 * 1024 ]; 
    } 
}

ヒープメモリのログに参加し、我々は、印刷結果を得ます:

   我々は、我々は見てみましょう、我々はメモリをほぼ満たされているヒープ、BT1新しい未来を取得し、現在は99%です。

パブリック クラスメイン{
     公共 静的 ボイドメイン(文字列[]引数){
         バイト[] BT1、BT2。
        BT1 = 新しい バイト [60000 * 1024 ]; 
        BT2 = 新しい バイト [10000 * 1024 ]; 
    } 
}

その後、我々は、我々は、私たちのエデン領域が十分でなければならず、BT2を構築しましたBT1を構築し、コードから学ぶことができる、そして私たちのメモリは、それに対処する方法になります。我々は結果を見て

  我々はすでにGCを作ったが、それでも、我々はヒープメモリ上に直接置かラージオブジェクトを指示する、適合しない見ることができます。

2、古い時代にオブジェクトの長期生存。それは、15歳に達して、我々は、オブジェクトの古い家をシフトminorGC後に繰り返す、オブジェクトまたは生きた後、我々は対象年齢世代ヘッド内にあるオブジェクトの古い家、通常は15回、移動、です。

図3は、動的オブジェクトの年齢を決定します。

  これは非常に重要な理論的な知識である、それはおそらく、我々はminorGCを終えたときに、あるオブジェクトが、私たち遺族地域にある地域に配置され、オブジェクトでもよいおよそ、その後、分類は年齢を計算され、適合しませんそれは、1世代、プラス2世代の年齢すべての年齢の合計、プラス3の世代の年齢を数えることである順次歳となって最大の世代に、追加しますが、プロセスを追加し、あなたがm個のオブジェクトの世代の年齢に追加見つける、地域の合計サイズはMが含まれ、nは世代年齢オブジェクトは、古い時代に再配置されるためにメートルになります。この時間まで充填されています。オブジェクトは、50%を超えるサバイバーエリアである場合には、この時代を含むオブジェクトの背面には、古い時代に配置されています。

古い時代に直接的4、ラージオブジェクト。コードセグメントを見てください。

パブリック クラスメイン{
     公共 静的 ボイドメイン(文字列[]引数){
         バイト[] BT1。
        BT1 = 新しい バイト [90000 * 1024 ]; 
    } 
}

  上記の、私はその後、我々は内部に収まる必要がありedenが600Mよりも大きなオブジェクトを作成し、99%を占め、エデンに置かれたとき、我々はおそらく600Mオブジェクトを作成して知っています。まあ、古い時代に直接置きます。ここで設定可能なパラメータです。私はその後、パラメータを設定するために見るためのパラメータを設定します

-XX:PretenureSizeThreshold = 10000000 -XX:+ UseSerialGC -XX:+ PrintGCDetails   

パブリック クラスメイン{
     公共 静的 ボイドメイン(文字列[]引数){
         バイト[] BT1。
        BT1 = 新しい バイト [20000 * 1024 ]; 
    } 
}

   私たちは、それは古い時代の上に直接配置され、ラージオブジェクトのステートメント10Mオブジェクトは、我々はラフターゲット20Mを作成して、パラメータを設定します。minorGCのオブジェクト経験何度、あなたが合わないこの時間を利用して、生きていたかもしれないと思うには、JVMの仮想機会です、あなたは、可能な限り早期に私たちの古いへのそれを混ぜ、その上です。

5歳のスペース割り当ての保証メカニズム。

  実際には、我々minorGC前たびに、我々はプロセスでそれを見て、フルGCかもしれ一連の操作があるでしょう。

 

 私はカラフルなマップ上に説明します。我々はフルエデン地域、minorGCの必要性を取得すると、残りのスペースは、古い時代の大きさを見て優先順位を与えるだろう、歳の残りのスペースが不足している場合、我々は可能性が私たちの老後の残りのスペースでフルGC、あること私たちのエデン領域よりも少ないがminorGCオブジェクトの合計になります。

それは本当に小さい場合-XXを構成するとき、私たちがダウンし、我々は決定します。(デフォルトの設定よりもjdk8)-HandlePromotionFailureこのパラメータを、残りの歳を決定するために行くように設定されている場合、直接fullGC構成されていない場合各スペースの後minorGCの歳未満ならば、我々は古い時代の平均オブジェクトサイズを配置するたびに、その後、fullGCことminorGC未満です。それ以外の場合は、フルGCを必要としません。

エデンサバイバー(からとに)デフォルトの比率は8:1:1であるが、我々は-XXあるパラメータ最適化、JVMかもしれません:+ UseAdaptiveSizePolicyデフォルトパラメータを、私は-XXにそれを変更:-UseAdaptiveSizePolicyありません最適化、8維持:1:1の比を。

  私たちは、リサイクル可能なオブジェクトの種類を見てみましょう。

1、参照カウント法は、(基本的な必要性は、循環参照オブジェクトが破棄されることはない、それはメモリ不足であってもよいです)

  オブジェクトカウンタへの参照を追加し、その場所をいつでも参照し、カウンタがインクリメントされていない、障害に言及する場合、カウンタは1だけデクリメントされ、オブジェクト0のための任意の時間カウンタは、もはや使用されています。 

  GCのルーツは、一般に、ローカル変数、静的変数、ローカル変数などのメソッドスタックのスレッドのスタックをルート。

2、到達可能性解析アルゴリズム。

  基本的な考え方は、検索を開始するオブジェクトは、非ゴミオブジェクトとしてマークされて見つけるためにダウンノードへの出発点として、「GCのルーツ」オブジェクトと呼ばれる一連のアルゴリズムによって、残りのマークされていないオブジェクトはガベージオブジェクトがあるということです

図3に示すように、共通の参照型。

  強い参照、ソフト、弱、基準ファントム参照:Javaの参照型は、一般に、4つのタイプに分け 

輸入java.lang.ref.SoftReference。
輸入java.lang.ref.WeakReference。

パブリック クラスメイン{
     公共 静的 ボイドメイン(文字列[]引数){ 
        ユーザーユーザ = 新しいユーザー(); // 强引用 
        弱い参照<ユーザー>はuser2 = 新しい弱い参照<ユーザー>(新しいユーザー()); // 弱引用 
        SoftReference <ユーザー>ユーザー3 = 新しい SoftReference <ユーザー>(新しいユーザー()); // 软引用
    } 
}

  オブジェクト参照の一般的なタイプのソフトSoftReferenceにラップされたオブジェクトは、正常に回復することはないが、GC仕上げのリリースは、新しいオブジェクトのためのスペースを発見した後に、オブジェクトは、これらのソフト参照の外に回収されます。ソフト参照は、メモリに敏感なキャッシュを実装するために使用されています。 

図4に示すように、最終的な決意対象の生存を確定。

  ファイナライズの方法は、それはfinalizeメソッドでも、最後の実行オブジェクトが撤回されようとしている前に、あなたはロジックを記述することができますが、絶対にこれを書くつもりはお勧めしません、メモリのオーバーフローを引き起こし、オブジェクトを回復することはないそうですです私たちのオブジェクトを「救う」ことができます。

  でも到達可能性解析アルゴリズムのオブジェクトで到達でき、そしてそれは「Feisibuke」ではない、と彼らは、「保護観察」段階に一時的にしているこの時間は本当に、少なくとも再びマークプロセスを通過するために、オブジェクトの死を宣言します。 

  クラスのクラスを決定する方法は無駄です

1.クラスのすべてのインスタンスは、クラスのインスタンスが存在しないJavaヒープである、回収されています。

2.ロードしたクラスのClassLoaderが回収されています。

クラスオブジェクトに対応する3のjava.lang.Classはないどこにでも反射クラスにアクセスする方法によって、任意の場所で参照されていません。 

  最後に、我々はエスケープ解析を見てください。

    JVMは、ここでは三つのモード、すなわち、説明モデル、コンパイルおよび混合モード、この問題についての簡潔で、またはモンサークルの後ろに実行されます。

説明モデルは、行動をコンパイルし、この利点は非常にすべてのバイトコードのメモリなしでメモリ空間を節約しているマシンコードにラインJVMバイトコードを実行され、内部の低動作効率を詰めますが、高速で開始されています。

コンパイル・モードと解釈モードの逆は、一度にすべてを実行するために、すべてのコンパイルされたマシンコードにJVMバイトコード、マシンコードの最初のものです。これが私たちの業務効率が、スペースを消費するリソースを改善します。

混合モードは、依然としてインタプリタを使用してコードパターンを実行し、上記の和であるが、いくつかの「ホット」コードのコンパイル・モードの実行、JVM典型的には混合モードコード実行を取ります。

のは、コードの一部を見てみましょう。

パブリック クラスメイン{
     パブリックユーザgetUserBeanTest(){ 
        ユーザーユーザー = 新しい新しいユーザー(); // ヒープに配置された
        リターンユーザー; 
    } 


    公共 ボイドuserBeanTest(){ 
        ユーザーユーザー = 新しい新しいユーザー(); // 優先順位は、毛髪および方法で配置しますスタック上。
    } 
}

すなわち、スタック上に配置することができる非常に小さな物体が存在し、明らかです。アップMyBatisの程度中秋節の休日、明日基本原理を達成することです。私たちのJVMを最適化するために継続するために数日のために

おすすめ

転載: www.cnblogs.com/cxiaocai/p/11520731.html