专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 Java堆内存和栈内存的区别

Java堆内存和栈内存的区别

更新时间:2022-07-07 12:00:28 来源:赢咖4 浏览1070次

Java 应用程序在计算机的RAM中编译和执行。每个应用程序都分配了一定数量的内存。在 RAM 中分配的内存称为应用程序内存。数据和代码存储在这里。分配给 Java 进程的内存量取决于多个因素,例如Java 运行时环境 (JRE)、操作系统、处理器等。JVM 将分配给进程的内存分为五个部分:Java堆栈、堆、类/方法区、程序计数器寄存器和本机方法堆栈。在本文中,赢咖4小编将对堆栈和堆内存进行介绍。

Java中的堆栈内存是什么?

堆栈内存是为进程分配的空间,用于存储所有函数调用、原始数据类型(如 int、double 等)以及函数的局部变量和引用变量。堆栈内存始终以后进先出 (LIFO)方式访问。在堆栈内存中,为每个执行的方法创建一个新的内存块。方法内的所有原始变量和对对象的引用都存储在此内存块中。当方法完成执行时,内存块从堆栈内存中清除,堆栈内存可供使用。只要创建它们的函数正在运行,堆栈中的值就存在。堆栈内存的大小是固定的,一旦创建就不能增长或缩小。

Java中的堆栈内存示例

下面是一个简单的 Java 程序,它包含三个方法main、addOne和addTwo。当这个程序执行时,我们将看到堆栈使用的逐步解释。

public class Main {
  public static int addOne(int input) {
    return input + 1;
  }
  public static int addTwo(int input) {
    return input + 2;
  }
  public static void main(String[] args) {
    int x = 0;
    x = addOne(x);
    x = addTwo(x);
  }
}

1.程序执行时,JVM首先执行main方法。调用 main 方法时,会在堆栈中为其分配一个块。方法中的变量被创建、赋值,然后存储在块中。

2.当从 main 方法调用addOne方法时,会在堆栈中分配一个新块。该方法的变量被创建并存储在块中。方法执行完成后,将值返回给调用方法(这里是主方法),并清除块。

3.同样,当调用addTwo方法时,会为其分配一个新块,并创建和存储变量。当方法完成执行时,将值返回给调用方法,并清除块。

4.最后,main方法完成其执行,并且从堆栈中清除该块。

Java中的堆内存是什么?

堆内存用于存储在 Java 程序执行期间创建的对象。对创建的对象的引用存储在堆栈内存中。堆遵循动态内存分配(内存在执行或运行时分配)并提供随机访问,与堆栈不同,堆栈遵循后进先出 (LIFO) 顺序。与堆栈相比,堆内存的大小很大。堆内存中未使用的对象由垃圾收集器自动清除。JVM堆内存可以分为三部分:

新一代或年轻一代

老一代或老一代

永久代

新一代或年轻一代

年轻代是分配所有新创建对象的地方。新一代依次有 3 个部分,Eden、Survivor1和Survivor2。所有新创建的对象都分配在伊甸园空间中。当 Eden 已满时,会发生一次次要的垃圾回收,并将活动对象移至Survivor1,然后移至Survivor2. Survivor1 和 Survivor2 包含在次要垃圾收集中幸存下来的对象。在 Eden、Survivor1 和 Survivor2 中幸存下来的对象将被移至终身代。在年老代中,垃圾收集的频率较低,因此使用 Survivor1 和 Survivor2 空间来确保只有长期存活的对象才会被移动到年老代。

老一代或老一代

年龄是为年轻代分配的对象设置的。当达到那个年龄时,那些活着的对象被移动到老年代。一般来说,长期存活的对象存储在老年代。主要垃圾收集在老年代运行以收集死对象。

永久代

JVM 使用永久代来存储有关类和方法的元数据。JVM 还将 Java 标准库存储在永久代中。该空间作为完整垃圾回收的一部分进行清理。

Java 中的堆内存示例

import java.util.ArrayList;
import java.util.List;
public class HeapMemory {
  public static void main(String[] args) {
    int x = 10;
    List < Integer > list = new ArrayList < > ();
    list.add(1);
    list.add(2);
    list.add(3);
  }
}

在上面的例子中,变量x分配在堆栈中,而对象列表分配在堆中。只有对列表对象的引用存储在堆栈中。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>