説明するためにJavaのメモリ管理の例

Java仮想マシンの実行時のメモリ割り当てマップ

スタック、ヒープ方式エリア紹介

1.スタック

  1.各メソッドは、スタックフレームが作成されると呼ばれる(格納されたローカル変数、オペランド、方法輸出)

  2. JVMは、各スレッドのスタックを作成し、スレッド情報(等実際のパラメータ、ローカル変数、)方法を実行するために記憶されます

  3.スレッドスタックプライベートに属し、スレッド間で共有することはできません!

  4.スタックのストレージ機能は、「最後のアウト、LIFO」であります

  スタックは、システムによって自動的に割り当てられ、速い!スタックは、連続したメモリ空間です!

2.ヒープ

  1.スタックが作成されたオブジェクトと配列を(配列はオブジェクトである)を格納するために使用され

  2. JVMは、すべてのスレッドで共有され、唯一のヒープであります

  3.ヒープが遅く、連続したメモリ領域の割り当てが柔軟ではありません!

3.メソッド領域

  1. JVMは、すべてのスレッドで共有一方向のみの領域です!
  3が常に同じまたは一意になり、プログラムの内容を格納するために使用されます。(クラスオブジェクトタイプ情報[]、静的変数、文字列定数、等)

サンプルコード

class Point {
    private double x;
    private double y;
    Point(double x1, double y1) {
        x = x1;
        y = y1;
    }
    public double getX() { return x; }
    public double getY() { return y; }
    public void setX(double i) { x = i; }
    public void setY(double i) { y = i; }
}
class Circle {
    private Point o;
    private double radius;
    Circle(Point p, double r) {
        o = p;
        radius = r;
    }
    public void setO(double x, double y) {
        o.setX(x);
        o.setY(y);
    }
    public Point getO() { return o; }
    public double getRadius() { return radius; }
    public void setRadius(double r) { radius = r; }
    public double area() { return 3.14 * radius * radius; }
    Circle increaseRadius() {
        radius++;
        return this; 
    }
}
public class TestCircle {
    public static void main(String args[]) {
        Circle c1 = new Circle(new Point(1.0, 2.0), 2.0);
        System.out.println("c1:" + c1.getO().getX());
        c1.setO(5, 6);
        System.out.println(c1.increaseRadius().increaseRadius().area());
    }
}

コンストラクタ円C1 =新しいサークル(新しいポイント(1.0,2.0)、2.0)解析.;

1.円C1

まず、スタック内のC1への参照を作成して、アドレスを指していることは不明です

名前のファイル

2.新しいポイント(1.0,2.0)

ポイントXYの変数の開始時に、ヒープ内のPointオブジェクトを作成し、すべて0です

名前のファイル(1)

スタック内のX1、Y1を作成し、ポイントXY、に割り当てられたメモリの割り当てが設定示すように完了したとき

名前のファイル(1)

コンストラクタは直ちに解放スタックX1、Y1空間内で、完了した後

名前のファイル(1)

3.ヒープに新しいサークルサークルオブジェクトを作成(新たな点(1.0,2.0)、2.0)

同様に、基準値作成したばかりの零サークル・オブジェクト・タイプである場合、ベース変数の値は、次に、コンストラクタに、0であり、点Pとわずかスタックで作成された2.0 R Pointオブジェクトの値を作成します

名前のドキュメント(3)

その後、円のポイントOポイント初期化要素内の2つの要素は、半径値が2.0になります

名前のファイル(4)

コンストラクタが完了すると、スタック内のrとpは直ちに解放します

最終的に円オブジェクト点C1円C1 =新しいサークル(新しいポイント(1.0,2.0)、2.0)。

名前のファイル(5)

二. c1.getO().getX()

C1指摘ポイントを得るGETO最初の呼び出しは、スタック内の基準点Oの参照を作成します

次に、Xの値を返すのgetX()を呼び出して、スタック内のXの値を格納するために使用される一時的なオブジェクトを作成します

名前のファイル(6)

印刷が完了した後、一時的なオブジェクトがクリーンアップされます

三 c1.setO(5,6);

以前の研究の後、私たちは、これは非常に単純であると信じて、

一時変数の瀬戸()の端部がクリーンアップされた後、C1 Pointオブジェクトの値を変更し、メモリ一時変数X = 5.0、Y = 6.0、割り当てで作成されました。

四c1.increaseRadius()。increaseRadius()領域()关于この

まず、C1コールincreaseRadius()メソッドは、可変半径+ 1は、その後、一時参照increaseRadius()メソッド再び半径+ 1、リターンによって呼び出されるように、一時的にスタックに格納されているサークルのクラスを参照し、オブジェクト点C1を返します一時的な参照プッシュは、取得するための最終手段)は、一時変数領域(で呼び出した後、エリアの半径を大きくC1を2つの一時変数内のステートメントの完了直後にスタックをクリーンアップ

名前のファイル(7)

メモリ割り当て静的変数

コード

class Cat {
    public static int num = 0;
    String name;

    Cat(String name) {
        this.name = name;
        ++num;
    }
}
public class Main {
    public static void main(String[] args) {
        Cat c1 = new Cat("mimi");
        Cat c2 = new Cat("miao");
        System.out.println(Cat.num);
    }
}

すべての文字列と静的メンバ変数の静的な型がプロセスゾーンにあらかじめロードされます

図メモリ分布に示すようにそのため、上記のコードは、実行され、C1と考えることができ、要素法を対応するスタック領域内の基準点を有するc2は

名前書類(8)

注記

需要注意的是,栈内元素在使用完成后会立刻被清理,但是堆内创建的对象并不会立刻消失,而是在垃圾回收器启动回收后才会消失,而为了性能考虑,在内存充沛时,垃圾回收器并不会经常运行.所以可能某个元素已经空置了很久但是仍未被回收.
class Point {
    int x, y;

    Point(int _x, int _y) {
        x = _x;
        y = _y;
    }        //_x,_y在构造函数运行完成后会立刻消失
}

public class Main {
    public static void main(String[] args) {
        Point p1 = new Point(1, 2);
        Point p2 = new Point(2, 3);
        p1 = p2;         //p1之前所指向的Point对象已经成为空置垃圾,但是不会被立刻回收
    }
}

おすすめ

転載: www.cnblogs.com/INnoVationv2/p/12321197.html