内存管理 Java

什么是堆栈内存?

Java 中的堆栈是内存的一部分,其中包含方法、局部变量和引用变量。堆栈内存始终按后进先出的顺序引用。局部变量在堆栈中创建。

什么是堆内存?

堆是内存中的一部分,其中包含对象,也可能包含引用变量。实例变量在堆中创建。

内存分配 Java

内存分配 Java 是在程序中留出虚拟内存部分来存储变量和结构和类的实例的过程。但是,在声明时不会将内存分配给对象,而只会创建引用。对于对象的内存分配,使用 new() 方法,因此对象始终在堆上分配内存。

这个 Java 内存分配分为以下部分:

  1. 代码
  2. 静止

为了实现内存的有效管理,需要对内存进行这种划分。

  • 这个 部分包含您的 字节码.
  • 这个 内存部分包含 方法、局部变量和引用变量。
  • 这个 部分包含 对象 (也可能包含参考变量)。
  • 这个 静止 部分包含 静态数据/方法.

局部变量和实例变量之间的区别

实例变量 被宣布 在类中但不在方法中

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创建一个框架。

Java 栈和堆

m1 中的变量 X 也将在堆栈中 m1 的框架中创建。(见下图)。

Java 栈和堆

方法 m1 正在调用方法 m2。在堆栈 java 中,在框架 m2 之上为 m1 创建新的框架。

Java 栈和堆

Java 栈和堆

变量 b 和 c 也将在堆栈中的框架 m2 中创建。

public void m2(int b){
boolean c;
}

Java 栈和堆

相同的方法 m2 正在调用方法 m3。再次在堆栈顶部创建框架 m3(见下图)。

Java 栈和堆

Java 栈和堆

现在假设我们的方法 m3 正在为“Account”类创建一个对象,该对象有两个 实例变量 int p 和 int q。

Account {
             Int p;
             Int q;
       }

这是方法 m3 的代码

public void m3(){
	Account ref = new Account();
	// more code
}

语句 new Account() 将在堆中创建一个帐户对象。

Java 栈和堆

引用变量“ref”将在堆栈 java 中创建。

Java 栈和堆

赋值“=”运算符将使引用变量指向堆中的对象。

Java 栈和堆

一旦该方法完成执行,控制流将返回到调用方法。在本例中为方法 m2。

Java 栈和堆

方法 m3 的堆栈将被清除。

Java 栈和堆

由于引用变量不再指向堆中的对象,因此它将有资格进行垃圾收集。

Java 栈和堆

一旦方法 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?

垃圾收集 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) 保存、编译并运行代码。如图所示,创建了两个对象和两个引用变量。


垃圾收集机制

步骤3) 取消注释第 20,21,22、XNUMX、XNUMX 行。保存、编译并运行代码。

步骤4) 如下图所示,两个引用变量指向同一个对象。

垃圾收集机制

步骤5) 取消注释第 23 行和第 24 行。编译、保存并运行代码

步骤6) 如下图所示,s2 变为空,但 s3 仍然指向该对象,并且不符合 Java 垃圾收集的条件。

垃圾收集机制

步骤7) 取消注释第 25 行和第 26 行。保存、编译并运行代码

步骤8) 此时,没有任何引用指向该对象,并且该对象可以被垃圾回收。它将被从内存中删除,并且无法将其恢复。

学习垃圾收集器

如何删除对象 Java?

1)如果您想让您的对象符合垃圾收集的条件,请将其引用变量分配给null。

2) 原始类型不是对象。它们不能被赋值为 null。

如何删除对象 Java

概要:

  • 当调用一个方法时,会在堆栈顶部创建一个框架。
  • 一旦方法完成执行,控制流将返回到调用方法,并且其相应的堆栈框架将被刷新。
  • 局部变量在堆栈中创建
  • 实例变量是在堆中创建的,并且是其所属对象的一部分。
  • 引用变量是在堆栈中创建的。