あなたはそれのそれらのものJVMのメモリを知っていますか?

序文

プログラマはC言語の開発では、メモリ管理は、各オブジェクトのライフサイクルを担当しなければならず、そこからへ。
あなたにJavaプログラマは、仮想マシンのメモリ管理の助けを借りて、自由な操作を一致させる必要はありません、メモリリークやメモリオーバーフローの問題新しいオブジェクトのそれぞれのためにも発生しにくいですが、それは正確に理由はメモリ管理でありますメモリリークがあった後、仮想マシンに、調査プロセスに大きな困難を引き起こし、プログラムを実行します。だから、唯一のコードのさまざまな計画を立てることができるように、Java仮想マシンの動作機構を理解します。本稿では、それらのものの例は、HotSpot仮想マシンについて話をします。

メモリを管理するためのJava仮想マシンは、いくつかの異なるデータ領域に分割されます。


WEBP

Javaヒープ

Javaヒープがメインオブジェクト・インスタンスを格納するためのメモリ領域のすべてのスレッドで共有され、Java仮想マシン仕様そのような説明:全ての例、およびデータオブジェクトはヒープ上に割り当てられます。オブジェクト用のメモリを割り当てることは、ヒープメモリからメモリの分割の大きさを決定することで、二つの方法が通常存在します。

図1に示すように、ポインタ衝突法
仮定Javaヒープメモリがいっぱいになる、ポインタとして分割点を介して、メモリを割り当てる必要がある、異なる側にある割り当てられ、空きメモリは、唯一の自由端にポインタを移動させる必要があります物体距離の等しいサイズ。

図2に示すように、フリー・リスト方式
事実は、Javaヒープメモリがフルでない、JVMを介して、互いにインターリーブ割り当てられ、空きメモリは、メモリブロックのリストは、情報が利用可能である記録維持分注動作が発生した場合、リストから求めメモリの十分に大きなブロックがオブジェクト・インスタンスに割り当て、及び更新リストに記録されています。

オブジェクトの作成は、非常に頻繁な動作でマルチスレッドの問題が考慮すべきヒープメモリ割り当てShihai、オブジェクトをメモリ割り当て、ポインタ、またはレコードを更新するために、まだ可能ではない、オブジェクトBながらこの問題を解決するために、元のメモリに割り当てられています2つのオプションがあり問題は:
1、CASを使用して、データ更新操作のアトミック性を保証する;
2、メモリ割り当ての挙動が異なる空間で実行スレッド、に従って分割され、各スレッドのスタックは、Java内のメモリのブロックを事前に割り当て、ローカルバッファに割り当てられたスレッド(ローカル割当バッファ、TLABスレッド)と呼ばれます 。

Javaスタック

Javaスレッドスタックは、各スレッドのJavaスタックプライベートで、各スレッドは、メソッドのスタックフレームの変数テーブルの実装に対応するスタックフレーム(スタック・フレーム)を作成しますローカル変数を格納するための責任があり、オペランドスタック、ダイナミックリンクメソッドとリターンアドレスやその他の情報。各メソッド呼び出し、プロセスを押すとポップのJavaスタックフレームスタックの等価。

WEBP

ローカル変数テーブルメソッドパラメータおよびメソッド内で定義されたローカル変数を格納するための、サイズは、メソッドが動作中に変化しない、コードのコンパイル時に決定されています。可変スロット(スロット)のローカル変数テーブルは、記憶の最小単位、スロットブール、バイト、文字、ショット、記憶の各可能な整数、フロート、基準長と二重ためRETURNADDRESSタイプと32ビットのデータを、64ビットのデータ・タイプ仮想機会は、2つの連続するスロットスペースを割り当てる高い方法を整列させます。

この方法は、すなわち、非静的メソッドから、パラメータリストの順序に従って参照デフォルトを保存し、この方法では、キーワードによりアクセスすることができ、プロセスパラメータオブジェクトのインスタンスのローカル変数テーブルスロット0、インスタンスである場合、メソッドを実行するときスロット割り当ては、定義の内部変数スロット割り当て順序の残りのためのプロセスを開始します。

class test {
    public int calc(int a, int b, String operation) {
        operation = "+";        return  a + b;
    }    public void main(String args[]) {
        calc(100, 200, "+");
    }
}

对应的局部变量表如下:


WEBP


使用 javap -c 命令查看方法calc的字节码


WEBP

其中iload_1和iload_2分别从局部变量表中的第1位和第2位中加载数据。

方法区

方法区和Java堆一样,是所有线程共享的内存区域,用于存放已被虚拟机加载的类信息、常量、静态变量和即时编译器编译后的代码等数据。
运行时常量池是方法区的一部分,用于存放编译期间生成的各种字面常量和符号引用。

指令计数器

指令计数器是线程私有的,每个线程都有独立的指令计数器,计数器记录着虚拟机正在执行的字节码指令的地址,分支、循环、跳转、异常处理和线程恢复等操作都依赖这个计数器完成。如果线程执行的是native方法,这个计数器则为空。

对象的内存布局

对象在内存中布局可以分成三块区域:对象头、实例数据和对齐填充。
1、对象头
对象头包括两部分信息:运行时数据和类型指针,如果对象是一个数组,还需要一块用于记录数组长度的数据。

1.1ランタイム・データは、ハッシュコード(ハッシュコード)を含む、GC世代年齢ロック状態フラグスレッドがロックを保持し、ロックIDタイムスタンプに向けて付勢され、32ビットおよび64ビットの仮想マシンのデータのこの部分32ビットおよび64ビットの長さは、正式に「マーク・ワード」として知られています。マークワードは、限られたスペースに格納されている限り多くのデータを得るために、非固定データ構造であるように設計されています。
32ビットの仮想マシン、次のようにオブジェクトの状態は、32ビット、4ビットストレージオブジェクト世代年齢、2ビットロックフラグ格納アドレス、0に固定された1ビットの25bitのハッシュコードマークワード・ストア・オブジェクトをロックしていません。


WEBP


次のように格納されたコンテンツを他の状態の下でマークWordを(軽量、ヘビーロックをロックGCロックは、ロックをバイアスすることができます)。


WEBP


1.2は、このポインタによりオブジェクトのメタデータは、仮想マシンの最初のクラスのオブジェクト・ポインタ・ポイントのタイプは、オブジェクト・クラスのどのインスタンスを決定することができます。

図2に示すように、データの例
データのインスタンスのフィールドタイプは、親クラスから継承し、格納順序のこの部分は、フィールドにおける仮想マシンとソースシーケンスで定義された割り当てポリシーに影響されるなど、プログラムコードで定義されています。
図3に示すように、アライメントパディング
ようにホットスポット自動メモリ管理は、オブジェクトの開始アドレスが8のデータオブジェクトヘッダ倍数、すなわち、オブジェクトのサイズが8バイトの整数倍である必要があり、8バイトの整数倍でなければならない必要があるためインスタンス・データは、8の整数倍ではないバイト場合には、アライメント完了によって充填される必要があります。



おすすめ

転載: blog.51cto.com/14028890/2409623