Javaのメモリ機構を図解で詳しく解説(コード付き)
Javaはメモリをスタックメモリとヒープメモリの2種類に分けます。関数内で定義されているいくつかの 変数 および オブジェクト の reference 変数は、すべて関数のスタック メモリに割り当てられます。 変数がコード ブロックで定義されている場合、Java はオンになります。スタック この変数にメモリ領域を割り当てます。変数のスコープを超える場合 (たとえば、関数 A で関数 B を呼び出し、関数 B で変数 a を定義し、変数 a のスコープは関数 B のみであり、関数内で実行されます)。 B その後、変数 a は自動的に破棄され (変数 a に割り当てられたメモリはリサイクルされます)、Java は変数に割り当てられたメモリ空間を自動的に解放し、そのメモリ空間はすぐに他の目的に使用できるようになります。 ヒープメモリは、new
によって作成されたメモリ配列を格納するために使用され、ヒープに割り当てられたメモリは、Java仮想マシンの自動ガベージコレクタによって管理されます。 ヒープ内に配列またはオブジェクトを生成した後、スタック内の特殊変数を定義して、スタック内の変数の値がヒープ メモリ内の配列またはオブジェクトの最初のアドレスと等しくなるようにすることもできます。スタック内の変数は、配列またはオブジェクトの参照変数になります。 スタック内の変数を使用して、プログラム内でヒープ内の配列またはオブジェクトにアクセスできます。参照変数は、配列またはオブジェクトに名前を付けるのと同じです。物体。 参照変数は、定義時にスタックに割り当てられる通常の変数であり、プログラムが他のスコープ外で実行された後に解放されます。配列とオブジェクトはヒープ内に割り当てられます。new によって生成された配列またはオブジェクト ステートメントが配置されているコード ブロックの外でプログラムが実行された場合でも、配列とオブジェクトによって占有されていたメモリは解放されません。配列とオブジェクトを指す参照変数が存在しない場合、それらはガベージとなり、後で不定の時点でガベージ コレクターによって収集 (解放) されます。これは、Java がより多くのメモリを消費する理由でもあります。実際、スタック内の変数はヒープ メモリ内の変数を指します。これは Java のポインタです。 コード例 Demo1: 単一オブジェクトの作成
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年龄:"+age); } } public class Demo1 { public static void main(String[] args) { Person per = new Person() ; } }
のアクセスアドレスであり、属性名や年齢などのオブジェクトの具体的な内容はヒープメモリに格納されます。 per オブジェクトはインスタンス化されただけで特定の値が割り当てられていないため、デフォルト値が設定されています。 stringのデフォルト値は
null、int型のデフォルト値は0です。前述したように、ヒープ メモリ空間は new キーワードを使用して開く必要があります。
コード例デモ2: 複数のオブジェクトの作成
class Person {
String name ;
int age ;
public void tell() {
System.out.println("姓名:"+name+",年龄:"+age);
}
}
public class Demo2 {
public static void main(String[] args) {
Person per1 = new Person() ;
Person per2 = new Person() ;
per1.name="张三" ;
per1.age=30 ;
per2.age=33 ;
per1.tell();
per2.tell();
}
}
Key概念: クラスは配列と同様、参照型です。参照型とは複数のスタック メモリが同じヒープ メモリを指すことができるということを、参照渡しの簡単な例を見てみましょう。
コード例 Demo3: 1 を渡すオブジェクト参照
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年龄:"+age); } } public class Demo3 { public static void main(String[] args) { Person per1 = new Person() ; Person per2 = per1 ;//-------注意-------- per1.name="张三" ; per1.age=30 ; per2.age=33 ; per1.tell(); per2.tell(); } }
プログラムの実行結果は次のとおりです:
プログラムの実行結果から、 2 つのオブジェクトの出力内容が同じであることがわかります。 . 実際には、1つのヒープメモリ空間の使用権を複数のスタックメモリ空間に移すことを指します。 このプログラムのメモリ割り当て図は、各スタックメモリ空間で変更できます。は次のとおりです:
图1-3 对象引用的传递内存分配
图1-3 对象引用的传递内存分配(续)
注意:上述实例中对象per2没有堆内存空间,这是因为对象per2只进行声明操作,也没有进行实例化操作。只是使用new关键字,实例化以后才会有堆内存空间
代码实例Demo4:对象引用传递2
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年龄:"+age); } } public class Demo4 { public static void main(String[] args) { Person per1 = new Person() ; Person per2 = new Person() ; per1.name="张三" ; per1.age=30 ; per2.name="李四" ; per2.age=33 ; per2=per1 ;//-----注意---- per1.tell(); per2.tell(); } }
上述运行程序结果为:
从程序的输出结果可以发现跟Demo3差不多。不过内存分配发生了一些变化,具体如下所示:
图1-4 (垃圾对象)的产生
注意点:
1.Java本身提供垃圾收集机制(Garbage Collection,GC),会不定期释放不用的内存空间,只要对象不用了,就会等待GC释放空间,如上面堆内存中的name="李四";age=33。
2.一个栈内存只能指向一个堆内存空间,如果要想指向其他堆内存空间,则必须先断开已有的指向,才能分配新的指向。
Java中常见的内存区域
在Java中主要存在4块内存空间,这些内存的名称及作用如下:
1.栈内存空间:保存所有对象的名称。
2.堆内存空间:保存每个对象的具体属性内容。
3.全局数据区:保存static类型的属性值。
4.全局代码区:保存所有的方法定义。
以上がJavaのメモリ機構を図解で詳しく解説(コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

intellijideaultimatiateバージョンを使用してスプリングを開始します...

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

データベースクエリにTKMYBATISを使用する場合、クエリ条件を構築するためにエンティティクラスの変数名を優雅に取得する方法は一般的な問題です。この記事はピン留めします...

Spring Project Startupにおける円形依存関係のランダム性を理解してください。春のプロジェクトを開発するとき、プロジェクトの起動時に循環依存関係によって引き起こされるランダム性に遭遇する可能性があります...
