メモリ管理 Java
スタックメモリとは何ですか?
Java のスタックは、メソッド、ローカル変数、および参照変数を含むメモリのセクションです。 スタック メモリは常に後入れ先出しの順序で参照されます。 ローカル変数はスタック内に作成されます。
ヒープメモリとは何ですか?
ヒープは、オブジェクトを含み、参照変数も含む可能性のあるメモリのセクションです。インスタンス変数はヒープ内に作成されます。
メモリ割り当て Java
メモリ割り当て Java 構造体やクラスの変数やインスタンスを格納するために、プログラム内で仮想メモリ セクションを確保するプロセスです。 ただし、宣言時にオブジェクトにメモリが割り当てられるのではなく、参照のみが作成されます。 オブジェクトのメモリ割り当てには new() メソッドが使用されるため、オブジェクトには常にヒープ上のメモリが割り当てられます。
私達の Java メモリ割り当ては次のセクションに分かれています。
- ヒープ
- スタック
- CPコード
- 静的
メモリを効果的に管理するには、このメモリの分割が必要です。
- 私達の コード セクションにはあなたの内容が含まれています バイトコード.
- 私達の スタック メモリのセクションには以下が含まれます メソッド、ローカル変数、および参照変数。
- 私達の ヒープ セクションに含まれるもの オブジェクト (参照変数も含まれる場合があります)。
- 私達の 静的 セクションに含まれるもの 静的データ/メソッド.
ローカル変数とインスタンス変数の違い
インスタンス変数 宣言されています クラス内ではあるがメソッド内ではない
class Student{
int num; // num is instance variable
public void showData{}
ローカル変数 宣言されている 内部 a を含む方法 方法 引数.
public void sum(int a){
int x = int a + 3;
// a , x are local variables;
}
スタックとヒープの違い
詳しくはこちら こちらをご覧いただくか、 ビデオにアクセスできない場合
これをよりよく理解するために例を見てみましょう。メインメソッドがメソッドm1を呼び出すとします。
public void m1{
int x=20
}
スタック Java では、メソッド m1 からフレームが作成されます。
m1 の変数 X もスタック内の m1 のフレームに作成されます。 (下の画像を参照)。
メソッド m1 がメソッド m2 を呼び出しています。 スタック java では、フレーム m2 の上に m1 の新しいフレームが作成されます。
変数 b と変数 c もスタック内のフレーム m2 に作成されます。
public void m2(int b){
boolean c;
}
同じメソッド m2 がメソッド m3 を呼び出しています。ここでもフレーム m3 がスタックの一番上に作成されます (下の画像を参照)。
ここで、メソッド m3 がクラス「Account」のオブジェクトを作成しているとします。このオブジェクトには XNUMX つのオブジェクトがあります。 インスタンス変数 int p と int q。
Account {
Int p;
Int q;
}
メソッド m3 のコードは次のとおりです。
public void m3(){
Account ref = new Account();
// more code
}
new Account() ステートメントは、アカウントのオブジェクトをヒープに作成します。
参照変数「ref」はスタックjavaに作成されます。
代入「=」演算子は、ヒープ内のオブジェクトを指す参照変数を作成します。
メソッドの実行が完了すると、制御フローは呼び出し元のメソッドに戻ります。この場合、メソッド m2 です。
メソッド m3 からのスタックはフラッシュされます。
参照変数はヒープ内のオブジェクトを指さなくなるため、ガベージ コレクションの対象になります。
メソッド m2 の実行が完了すると、メソッドはスタックからポップアウトされ、そのすべての変数はフラッシュされ、使用できなくなります。
メソッド m1 についても同様です。
最終的に、制御フローはプログラムの開始点に戻ります。通常は「main」メソッドです。
Object がそのインスタンス変数として参照を持っている場合はどうなるでしょうか?
public static void main(String args[]) {
A parent = new A(); //more code } class A{ B child = new B(); int e; //more code } class B{ int c; int d; //more code }
この場合、参照変数「child」がヒープ内に作成され、次に示す図のように、そのオブジェクトがそのオブジェクトを指します。
ガベージコレクションとは Java?
ガベージコレクション Java プログラムが自動的にメモリ管理を行うプロセスです。ガベージコレクター(GC)は未使用のオブジェクトを見つけて削除し、メモリを再利用します。 Javaオブジェクトの動的なメモリ割り当ては、いくらかのメモリを使用する new 演算子を使用して実現され、オブジェクトの使用に対する参照があるまでメモリは割り当てられたままになります。
オブジェクトへの参照がなくなった場合、そのオブジェクトは不要であるとみなされ、そのオブジェクトが占有していたメモリは再利用できます。オブジェクトを明示的に破棄する必要はありません。 Java 割り当て解除を自動的に処理します。
これを実現する技術は次のように知られています。 ガベージコレクション。 メモリの割り当てを解除しないプログラムは、システムに割り当てるメモリがなくなったときに最終的にクラッシュする可能性があります。 これらのプログラムには、 メモリリーク。 ガベージコレクション Java 自動的に起こる プログラムの存続期間中、メモリの割り当てを解除する必要がなくなるため、メモリ リークが回避されます。
C言語では、free()関数を使用して動的に割り当てられたメモリを解放するのはプログラマの責任です。 Java メモリ管理のリード。
注意: すべてのオブジェクトはメモリのヒープ セクションに作成されます。これについては、後のチュートリアルで詳しく説明します。
例: ガベージコレクタの仕組みを学ぶ Java
ステップ1) 次のコードをエディターにコピーします。
class Student{
int a;
int b;
public void setData(int c,int d){
a=c;
b=d;
}
public void showData(){
System.out.println("Value of a = "+a);
System.out.println("Value of b = "+b);
}
public static void main(String args[]){
Student s1 = new Student();
Student s2 = new Student();
s1.setData(1,2);
s2.setData(3,4);
s1.showData();
s2.showData();
//Student s3;
//s3=s2;
//s3.showData();
//s2=null;
//s3.showData();
//s3=null;
//s3.showData();
}
}
ステップ2) コードを保存、コンパイル、実行します。 図に示すように、XNUMX つのオブジェクトと XNUMX つの参照変数が作成されます。
ステップ3) 行番号 20,21,22、XNUMX、XNUMX のコメントを解除します。 コードを保存、コンパイル、実行します。
ステップ4) 以下の図に示すように、XNUMX つの参照変数が同じオブジェクトを指しています。
ステップ5) 行番号 23 と 24 のコメントを外します。コードをコンパイル、保存、実行します。
ステップ6) 以下の図に示すように、s2 は null になりますが、s3 は依然としてオブジェクトを指しているため、Java ガベージ コレクションの対象にはなりません。
ステップ7) 行番号 25 と 26 のコメントを外します。コードを保存、コンパイル、実行します。
ステップ8) この時点では、オブジェクトを指す参照は存在しないため、ガベージ コレクションの対象になります。 これはメモリから削除され、元に戻す方法はありません。
オブジェクトを削除する方法 Java?
1) オブジェクトをガベージ コレクションの対象にしたい場合は、その参照変数を null に割り当てます。
2) プリミティブ型はオブジェクトではありません。 null を割り当てることはできません。
概要
- メソッドが呼び出されると、スタックの最上部にフレームが作成されます。
- メソッドの実行が完了すると、制御の流れは呼び出し側メソッドに戻り、対応するスタック フレームがフラッシュされます。
- ローカル変数はスタック内に作成されます
- インスタンス変数はヒープ内に作成され、それらが属するオブジェクトの一部になります。
- 参照変数はスタック内に作成されます。



















