JVM注:Java仮想マシンのメモリ構造

序文

あなたと一緒に以下の知見を起動し、Java仮想マシンのメモリ構造とメモリモデル(JMM)は前者が見ることができ、スタックなど、およそ次の話の内容で、実際には二つの異なるものである。この記事では。

以来、グローバル文字列定数プール(文字列プールまたは文字列リテラルプール) Java8次の例に、Java(登録商標)の異なるバージョンの異なる位置に配置されています。

  • ランタイムデータ領域

    データメモリを管理するJavaプログラムの実行中のJava仮想マシンを複数のゾーンに分割され、各ゾーンには、仮想マシンプロセスの年齢はいくつかの地域に存在するいくつかの地域で開始し、独自の目的やライフサイクルを持っていますスタートとエンドユーザーは、スレッドに依存して作成して破壊します。で、「Java仮想マシン仕様」の下では、Java仮想マシン管理メモリは、図1に示すように、以下のランタイム・データ領域が含まれています。しかし、これは単なる標準、であることを覚えているメソッド領域は、JVMの仕様ですが、Java 1.8永久**(PermGen空間)の前世代** **とJavaは、スペースの1.8元(メタスペース)**これであるような達成するための仕様の種類。

    ランタイムデータ領域

  • Javaヒープ

    ほとんどのアプリケーションでは、Javaヒープ(Javaヒープ)は、Java仮想マシン管理におけるメモリの最大の作品です。Javaヒープは、仮想マシンの起動時に作成されたメモリ領域のすべてのスレッドで共有されています。唯一の目的は、オブジェクトのインスタンスを格納するメモリ領域を変更するには、ほぼすべてのオブジェクトインスタンスがここでメモリを割り当てている、Java仮想マシンの仕様を記述です:所有对象以及数组都要在对上分配しかし、すべてのオブジェクトがもペアに割り当てられている分析技術の開発をし、JITコンパイラ技術はノンストップで、成熟する、スカラー最適化技術は、いくつかの微妙な変化をもたらすだろう置き換える脱出することは次第に少なくなり、絶対A。

    Javaのヒープのガベージコレクションのメインエリアはによって管理され、そのためしばしばも呼ばれる「GCヒープ。」現時点では、基本的なメモリリコールがゾーニング電話のアルゴリズムを採用している、それはまた、Javaヒープに細分化することができ新生代和老生代、その後、細かい点を分けることができEden空间From Survivor空间To Survivor空间というように。

    Javaヒープは、(ローカル割り当てバッファ= TLABスレッド)プライベートキャッシュを割り当て、複数のスレッドに分割することができ、それを保存したり、オブジェクトインスタンスどのように分割、どんなには、さらに目的を分割してJavaヒープは、スレッドで共有されているので、より良いにありますメモリ、またはより高速なメモリ割り当ての回復。(TODO:ガベージコレクションとメモリの割り当て)

    Java仮想マシンの仕様では、Javaヒープは、私たちのディスクスペースのように、限り、論理的に連続に、物理メモリ空間上で不連続であってもよいです。練習室では、-Xmxと-Xmsによって達成サイズを拡張することができます。ない場合はヒープ割り当てインスタンスへの十分なメモリが作成され、スタックはもはや広げることができない、それがスローされますOutOfMemoryError例外を。

  • メソッド地区

    同じ方法でJavaヒープ領域は、各スレッドは、仮想マシンでそのようなコンパイルされたコードとして、定数、静的変数、リアルタイムデータをロードされた主情報ストレージクラスに使用される共有メモリ領域です。メソッド領域で説明したように、Java仮想マシン仕様は、ロジックの一部ですが、それは非ヒープ(非スタック)と呼ばれる変種がありますが、その目的は、ヒープから区別されるべきです。

    HosSpost、より多くの人々「永久世代(PermGenスペース)」として知られている方法のエリアでは、二人はHotSpot仮想マシンの設計チームは、拡張ゾーンを収集するためにGCゾーニング方式に選んだのか、という理由だけで、自然界には等しくありません彼は、メソッド領域の永久的な実装を代表して言いました。このようなホットスポットのガベージコレクタは、特別な管理領域メモリ書き込みコードワークに保存されてますが、メソッド領域を実装する方法の詳細については、制約のJava仮想マシン仕様ずに、仮想マシンに所属することができ、メモリ管理の一環として、Javaヒープ管理としてすることができ同様のBEA、JRockitは、IBM J9仮想マシンをコンセプトに代わって永続的に存在していません。

    メソッド領域のためのJava仮想マシンの仕様限界は非常に緩和され、メモリのような連続Javaヒープを必要としない、あなたは再起動することができますJVMでスケーラブルな固定サイズを設定して、あなたはまた、ガベージコレクションを実装しないことを選択することができます。しかし、それは単に永久「永久」存在として名前の代わりにする方法、およびタイプ(TODO)の地域の主要な定数プールとアンロード、一般的に言えば、地域のこの部分の回復のために回復の対象として領域にデータを意味するものではありませんかなり弱い回復能力、特に非常に過酷な条件をアンロードタイプが、リカバリ領域のこの部分は確かに必要です。

    Java7から削除永遠の世代はゆっくりと、Javaヒープに移さネイティブヒープ、Javaヒープに転送リテラル(インターン文字列)、クラス静的変数(クラスの静的)に転送シンボリック参照(シンボル)を開始しました。Java8では、メタスペースは、不死化世代に置き換えます。ローカルメモリ空間要素(ネイティブ・メモリー)に記憶されているヒープ不死化生成データに割り当てられた領域とは異なり、それはVMに存在しないので、表示されないOutOfMemoryError異常。

    ここで最も重要なポイントの一つは、生きた世代に存在し、そのオブジェクトを格納JDK6の文字列定数プールは、あること。JDK7以降でヒープ内に存在し、そのリテラル(インターン文字列)を格納し、ヒープメモリアドレス文字列(とも呼ばれる文字列参照)が、文字列オブジェクトは、すべてのヒープです。基準シンボル(シンボル参照)と呼ばれるローカル・メモリ(ネイティブ・メモリー)に記憶されたテーブルはinterned string pool / StringTable、本明細書に参照格納されたテーブルの文字列定数である)String.internを(呼び出すときには、文字列を検出する文字列定数場合参照文字列定数プールは、新しい文字列その構造のオーバーヘッドを回避し、直接が返された場合、文字列は、参照プールに存在しない、加えて記録されます。その構造は、私たちの共通のハッシュテーブルに似ています。(TODO:ここで間違っている、私を修正してくださいフォローアップは、作品の全体説明を行うための情報へのより多くのアクセスとなります)

-XX:PermSize
方法区初始大小
-XX:MaxPermSize
方法区最大大小
超过这个值将会抛出OutOfMemoryError异常:java.lang.OutOfMemoryError: PermGen

-XX:MetaspaceSize 初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:
如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
-XX:MaxMetaspaceSize最大空间,默认是没有限制的。
-XX:MinMetaspaceFreeRatio在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
-XX:MaxMetaspaceFreeRatio在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集
复制代码
  • プログラムカウンタ

    プログラムカウンタは、それが実行される現在の行番号インジケータスレッドバイトコードとして見ることができる、小さなメモリ空間です。仮想マシンの概念モデルでは、この作業のバイトコードインタプリタは、命令を実行すべき次のバイトコードを選択するために、カウンタの値を変更する分岐、ループ、分岐、例外処理、および他の基本的な機能により、スレッド回復していることです私たちは、完了するために、カウンターに依存する必要があります。

    マルチスレッドJava仮想マシンは、順番に、プロセッサ実行時間(タイムスライス)を切り替えて割り当てられているので、スレッドによって実現され、さらに時間、処理スレッドは、一つの命令を実行します。そのため、各スレッドを実行するための適切な位置にスレッドの切り替えを復元するために、互いに独立して、独立した店舗の各スレッドの間、私たちは「プライベートスレッド」ためのメモリ領域のこのタイプを呼び出し、別のプログラムカウンタが必要ですメモリ。

    スレッドは、Javaメソッドを実行している場合、カウンタは、実行中の仮想マシンのバイトコード命令のアドレスを記録し、この方法は、ネイティブに実行されている場合、このカウンタ値が(Undenfined)nullです。このメモリ領域は、OOM Java仮想マシン仕様で異常を提供していない領域のみです。

  • Java仮想マシンのスタック

    プログラムカウンタと同じように、Java仮想マシンのスレッドスタックがプライベートで、彼と同じスレッドのライフサイクルに耳を傾けます。仮想マシンのスタックのJavaメモリモデルが記載された方法が行われる:スタックフレーム(スタックフレーム)を行う各メソッドは、同僚が作成され、ローカル変数テーブルを格納するため、オペランドスタック、動的リンク、方法出口情報を点灯させます。実行手順が完了するまで各方法は、仮想マシン内のスタックをプッシュするプロセスの対応するスタックフレームと呼ばれます。

    多くの場合、Javaのメモリヒープ(ヒープ)とスタックメモリ(スタック)に分割された、タスクは少しラフだったこと、Javaのメモリ領域を分割し、これよりも実際には複雑です。人気のこの部門は、メモリ割り当てられたメモリ領域のオブジェクトと、ほとんどのプログラマが最も懸念していることのみを提案することができます最も密接にこれら二つです。これはJavaヒープの簡単な説明がある上部の「ヒープ」と呼ぶが、その内容はそれよりもはるかにあり、かつ「スタック」は今、仮想マシンのスタック、または仮想マシンのスタックのローカル変数テーブルセクションについて話しています。

    ローカル変数既知のコンパイラのデータベースの様々な種類を格納するためのテーブル(boolean、byte、插入、short、int、float、long、double)、オブジェクト参照(referenceタイプ、彼は、オブジェクト自体と同等でない開始アドレスへのオブジェクト・ポインタを参照することができ、それは、点オブジェクトハンドルを表すことができますまたは他の場所)と、このオブジェクトに関連付けられたreturnAddressタイプ(アドレス)は、バイトコード命令を指します。

    64長項longdoubleデータのタイプは、2つのローカル変数コントロールを(取ることができるSlot)、残りのデータは、一種類のみを占有します。メソッドを入力するときに、このメソッドはスタックフレームに割り当てられたローカル変数のために多くのスペースを必要とし、コンパイル時に割り当てられたメモリ空間を完了するために必要なローカル変数は完全に方法の動作中に決定されたローカル変数テーブルのサイズを変更しません。

    Java仮想マシン仕様では、この領域のための2つの異常のために用意されています。スレッドスタックの深さが要求された仮想マシンの許容深さよりも大きい場合、スローされますStackOverflowError(最も典型的な再帰の終了値が設定されていない)例外を;場合展開がスローされます場合は、あなたが十分なメモリに適用することはできませんVMスタックの動的拡張は、(現在のJava仮想マシンのほとんどが動的に拡大することができますが、Java仮想マシン仕様では、仮想マシン・スタック、固定長することができます)OutOfMemoryError例外。

  • ネイティブメソッドスタック

    ネイティブメソッドスタックと仮想マシンが果たした役割をスタックに非常に似ているが、両者の差があるJavaスタック方式ネイティブメソッドのサービスを使用する(つまり、バイトコード)サービス、ネイティブメソッドスタック、仮想マシンを実行する仮想マシン仮想マシン仕様の必須、具体的な内容として、ネイティブメソッドスタック、データ構造および方法で使用何の言語が自由に仮想マシンにより実装することはできません。でも、いくつかの仮想マシン(日HotSpotのは)1つのネイティブメソッドスタックに直接入れて、仮想マシンをスタックします。

    仮想マシンのスタックと同様に、スタック領域のネイティブ方法も投げることができるStackOverflowErrorOutOfMemoryErrorの例外。

  • ダイレクトメモリ

    ダイレクトメモリ(ダイレクト・メモリ)が稼働している仮想マシンのデータ領域の一部ではない、またそれは仕様で定義されたJava仮想マシンのメモリ領域です。しかし、このメモリも頻繁に使用される、ともにつながる可能性がOutOfMemoryError異常なので、ここでは、以下の簡単な説明です。

    導入路(チャネル)およびI / Oモード時のバッファ(バッファ)に基づいていますJDK1.4新しく追加されたNIO(新しい入力/出力)タイプでは、彼が使用することができNative、その後、割り当てられたヒープメモリの外に直接ライブラリをJavaを通してヒープに格納されDirectByteBuffer、このメモリが動作するための基準としてオブジェクト。回避できるので、これはかなり、緑のいくつかのシナリオでのパフォーマンスを向上させることができJava、ヒープNative前後にパイル割り当てデータを。

    明らかに、このレベルのダイレクトメモリ割り当てを確実依然として機械の合計メモリサイズ、プロセッサのアドレス空間によって制限され、それはメモリであるため、Javaヒープのサイズによって限定されるものではないが。-Xmxおよびその他のパラメータを設定し、実際のメモリに応じて、仮想マシンのパラメータを設定するが、多くの場合、メモリを無視する場合、各メモリエリアサーバ管理者は、その結果、(物理的およびオペレーティングシステムレベルの制約を含む)全体的な物理メモリの制限よりも大きいです発生した動的拡張OutOfMemoryError異常。

  • 概要

    Java仮想マシンの深い理解の周志明バージョンからフィルムコンテンツの多くは、書籍の実行時定数プールとこれを取り扱う時に、ここでの記事のいくつかのシリーズを読んで、または比較的小さく、理解しやすいの話の本を見つけたが、より詳細なフォローアップが要約のためにこれをしたいので、ダウン書かれていません。

おすすめ

転載: juejin.im/post/5daeb86a5188257a73068a1a