专业的JAVA编程教程与资源

网站首页 > java教程 正文

一文读懂Java的“栈内存”[Stack]和“堆空间”[Heap]

temp10 2024-11-12 13:02:23 java教程 12 ℃ 0 评论

JVM将内存分为堆内存和堆内存。每当我们声明新的变量和对象、调用新方法、声明一个字符串或执行这些类似操作时,JVM将会从“栈内存”或“堆空间”中指定这些操作的内存。

栈内存(Stack Memory)

Java中的栈内存用于静态内存分配线程执行。方法的原始数据类型值和方法中引用对象(存在堆空间里)的引用

一文读懂Java的“栈内存”[Stack]和“堆空间”[Heap]

对该区域内存的访问按照后进先出(Last-In-First-Out)顺序进行。每当我们调用一个新方法时,就会在堆顶部创建一个新块,其中包含该方法的值,如原始数据类型变量和对象的引用。

当方法完成执行时,其相应的栈的帧被清除,流程返回到调用方法,并为下一个方法腾出空间。

栈内存有下面的特性:

  1. 随着新方法的调用和返回,它会增长和缩小。
  2. 栈内部的变量仅在创建它们的方法运行时存在。
  3. 当方法执行完成时,它将自动分配并释放。
  4. 如果此内存已满,则Java会抛出java.lang.StackOverFlowError 错误。
  5. 与堆内存相比,访问此内存速度更快。
  6. 该内存是线程安全的,因为每个线程都在其自己的栈中操作。
  7. 可以使用-Xss JVM参数来设置栈内存的大小。

堆空间

堆空间用于Java对象在运行时的动态内存分配新对象总是在堆空间中创建,对这些对象的引用存储在栈内存中。

这些对象具有全局访问权限,我们可以从程序的任何地方访问它们。

我们可以将这个内存模型分解成更小的部分,称为。它们包括:

  1. 年轻代:这是所有新对象被分配和老化的地方。当此区域填满时会进行一次小垃圾回收。
  2. 老年代:这是长期存活对象的存储位置。当对象被存储在年轻代时,会设置一个对象年龄的阈值,当达到该阈值时,该对象就会移动到老年代。
  3. 永久代:它由运行时类和程序方法的JVM元数据组成。

堆空间有下面的特性:

  1. 它通过包括年轻代、老年代和永久代在内的复杂内存管理技术进行访问。
  2. 如果堆空间已满,Java会抛出java.lang.OutOfMemoryError 错误。
  3. 与堆栈不同,这种内存不会自动释放。需要垃圾回收器来释放未使用的对象,以保持内存使用效率。
  4. 与栈不同,堆不是线程安全的,并且需要通过适当地同步代码来保护。
  5. 可以使用-Xms-Xmx JVM参数来设置堆内存的启动内存和最大内存的大小。

示例

现在让我们分析一段简单的Java代码:

class Person {
    int id;
    String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

public class PersonBuilder {
    private static Person buildPerson(int id, String name) {
        return new Person(id, name);
    }

    public static void main(String[] args) {
        int id = 23;
        String name = "John";
        Person person = null;
        person = buildPerson(id, name);
    }
}

让我们逐步分析:

  1. 当我们进入main() 方法时,会在栈内存中创建一个空间来存储该方法的基本数据类型和引用。
  • 栈内存直接存储原始数据类型整数id的值。
  • 在栈内存中创建类型为Personperson 对象的引用变量,它指向堆内存中实际对象。
  1. main() 调用参数化的构造器Person(int, String) 将在先前的栈的上方分配更多内存。这将保存:
  • 调用对象在栈内存中的this 对象引用。
  • 栈内存中的原始数据值id
  • 指向堆内存字符串池中实际字符串的String参数名称的引用变量。


  1. main()方法进一步调用buildPerson() 静态方法,这将在先前的栈内存之上进行内存分配。再次按照上述方式存储变量。
  2. 而新创建对象person (类型为Person )的所有实例变量都将被保存到堆内存中。

参考资料:

https://www.baeldung.com/java-stack-heap

https://www.digitalocean.com/community/tutorials/java-heap-space-vs-stack-memory

https://www.javatpoint.com/stack-vs-heap-java

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表