Java 堆栈和堆:Java 内存分配教程
什么是栈内存?
Java中的堆栈是一段内存,包含方法、局部变量和引用变量。堆栈内存始终以后进先出的顺序引用。局部变量在栈中创建。
什么是堆内存?
堆是内存的一部分,其中包含对象,也可能包含引用变量。实例变量在堆中创建
Java 中的内存分配
Java 中的内存分配 是在程序中预留虚拟内存部分以存储结构和类的变量和实例的过程。然而,内存并没有在声明时分配给对象,而只是创建了一个引用。对于对象的内存分配,使用了new()方法,所以对象总是在堆上分配内存。
Java内存分配分为以下几个部分:
- 堆
- 堆栈
- 代码
- 静态
这种内存划分是对其有效管理所必需的。
- 代码 部分包含您的 字节码 .
- 堆栈 内存部分包含方法、局部变量和引用变量。
- 堆 部分包含对象 (也可能包含引用变量)。
- 静态 部分包含静态数据/方法 .
局部变量和实例变量的区别
实例变量 在类中声明,但不在方法中
class Student{ int num; // num is instance variable public void showData{}
局部变量 被声明在内部 一个方法,包括 方法参数 .
public void sum(int a){ int x = int a + 3; // a , x are local variables; }
栈和堆的区别
如果视频无法访问,请单击此处
让我们举个例子来更好地理解这一点。
考虑一下你的 main 方法调用方法 m1
public void m1{ int x=20 }
在栈java中,会从方法m1创建一个frame。
m1 中的变量 X 也将在堆栈中的 m1 的帧中创建。 (见下图)。
方法 m1 正在调用方法 m2。在堆栈java中,在框架m1之上为m2创建了一个新框架。
变量 b 和 c 也将在堆栈中的帧 m2 中创建。
public void m2(int b){ boolean c; }
同样的方法 m2 正在调用方法 m3。再次在堆栈顶部创建一个框架 m3(见下图)。
现在假设我们的方法 m3 正在为“Account”类创建一个对象,它有两个实例变量 int p 和 int q。
Account { Int p; Int q; }
这是方法m3的代码
public void m3(){ Account ref = new Account(); // more code }
语句 new Account() 将在堆中创建一个 account 对象。
引用变量“ref”将在堆栈java中创建。
赋值“=”运算符将创建一个引用变量以指向堆中的对象。
一旦方法完成执行。控制流将返回到调用方法。在这种情况下是方法 m2。
方法 m3 的堆栈将被刷新。
由于引用变量将不再指向堆中的对象,因此可以进行垃圾回收。
一旦方法 m2 完成执行。它将被弹出堆栈,并且它的所有变量都将被刷新,不再可用。
对于方法 m1 也是如此。
最终,控制流将返回到程序的起点。这通常是“主要”方法。
如果 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