Stack Memory and Heap Space in Java – Java中的堆栈内存和堆空间

最后修改: 2018年 7月 12日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

To run an application in an optimal way, JVM divides memory into stack and heap memory. Whenever we declare new variables and objects, call a new method, declare a String, or perform similar operations, JVM designates memory to these operations from either Stack Memory or Heap Space.

为了以最佳方式运行应用程序,JVM将内存分为堆栈和堆内存。每当我们声明新的变量和对象、调用新的方法、声明一个字符串,或执行类似的操作时,JVM都会从堆栈内存或堆空间为这些操作指定内存。

In this tutorial, we’ll examine these memory models. First, we’ll explore their key features. Then we’ll learn how they are stored in RAM, and where to use them. Finally, we’ll discuss the key differences between them.

在本教程中,我们将研究这些内存模型。首先,我们将探讨它们的主要特征。然后,我们将学习它们是如何存储在RAM中的,以及在哪里使用它们。最后,我们将讨论它们之间的主要区别。

2. Stack Memory in Java

2.Java中的堆栈内存

Stack Memory in Java is used for static memory allocation and the execution of a thread. It contains primitive values that are specific to a method and references to objects referred from the method that are in a heap.

Java中的堆内存用于静态内存分配和线程的执行。它包含了特定于方法的原始值,以及从方法中引用的对象在堆中的引用。

Access to this memory is in Last-In-First-Out (LIFO) order. Whenever we call a new method, a new block is created on top of the stack which contains values specific to that method, like primitive variables and references to objects.

对该内存的访问是按后进先出(LIFO)的顺序进行的。每当我们调用一个新的方法时,就会在堆栈的顶部创建一个新的块,其中包含该方法的特定值,如原始变量和对象的引用。

When the method finishes execution, its corresponding stack frame is flushed, the flow goes back to the calling method, and space becomes available for the next method.

当方法执行完毕后,其对应的堆栈框架被刷新,流向回到调用方法,而空间则可用于下一个方法。

2.1. Key Features of Stack Memory

2.1.堆栈内存的主要特点

Some other features of stack memory include:

堆栈内存的其他一些特点包括。

  • It grows and shrinks as new methods are called and returned, respectively.
  • Variables inside the stack exist only as long as the method that created them is running.
  • It’s automatically allocated and deallocated when the method finishes execution.
  • If this memory is full, Java throws java.lang.StackOverFlowError.
  • Access to this memory is fast when compared to heap memory.
  • This memory is threadsafe, as each thread operates in its own stack.

3. Heap Space in Java

3.Java中的堆空间

Heap space is used for the dynamic memory allocation of Java objects and JRE classes at runtime. New objects are always created in heap space, and the references to these objects are stored in stack memory.

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

These objects have global access and we can access them from anywhere in the application.

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

We can break this memory model down into smaller parts, called generations, which are:

我们可以将这个内存模型分解成更小的部分,称为世代,它们是。

  1. Young Generation – this is where all new objects are allocated and aged. A minor Garbage collection occurs when this fills up.
  2. Old or Tenured Generation – this is where long surviving objects are stored. When objects are stored in the Young Generation, a threshold for the object’s age is set, and when that threshold is reached, the object is moved to the old generation.
  3. Permanent Generation – this consists of JVM metadata for the runtime classes and application methods.

These different portions are also discussed in the article Difference Between JVM, JRE, and JDK.

这些不同的部分也在JVM、JRE和JDK之间的区别一文中讨论。

We can always manipulate the size of heap memory as per our requirement. For more information, visit this linked Baeldung article.

我们总是可以根据我们的要求来操纵堆内存的大小。欲了解更多信息,请访问此链接的Baeldung文章

3.1. Key Features of Java Heap Memory

3.1.Java堆内存的主要特点

Some other features of heap space include:

堆空间的其他一些特点包括。

  • It’s accessed via complex memory management techniques that include the Young Generation, Old or Tenured Generation, and Permanent Generation.
  • If heap space is full, Java throws java.lang.OutOfMemoryError.
  • Access to this memory is comparatively slower than stack memory
  • This memory, in contrast to stack, isn’t automatically deallocated. It needs Garbage Collector to free up unused objects so as to keep the efficiency of the memory usage.
  • Unlike stack, a heap isn’t threadsafe and needs to be guarded by properly synchronizing the code.

4. Example

4.实例

Based on what we’ve learned so far, let’s analyze a simple Java code to assess how to manage memory here:

根据我们到目前为止所学到的知识,让我们分析一段简单的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);
    }
}

Let’s analyze this step-by-step:

让我们一步一步地分析一下。

  1. When we enter the main() method, a space in stack memory is created to store primitives and references of this method.
    • Stack memory directly stores the primitive value of integer id.
    • The reference variable person of type Person will also be created in stack memory, which will point to the actual object in the heap.
  2. The call to the parameterized constructor Person(int, String) from main() will allocate further memory on top of the previous stack. This will store:
    • The this object reference of the calling object in stack memory
    • The primitive value id in the stack memory
    • The reference variable of String argument name, which will point to the actual string from string pool in heap memory
  3. The main method is further calling the buildPerson() static method, for which further allocation will take place in stack memory on top of the previous one. This will again store variables in the manner described above.
  4. However, heap memory will store all instance variables for the newly created object person of type Person.

Let’s look at this allocation in the diagram below:

让我们在下图中看一下这种分配。

java heap stack diagram

5. Summary

5.总结

Before we conclude this article, let’s quickly summarize the differences between the Stack Memory and the Heap Space:

在结束这篇文章之前,让我们快速总结一下堆栈内存和堆空间的区别。

Parameter Stack Memory Heap Space
Application Stack is used in parts, one at a time during execution of a thread The entire application uses Heap space during runtime
Size Stack has size limits depending upon OS, and is usually smaller than Heap There is no size limit on Heap
Storage Stores only primitive variables and references to objects that are created in Heap Space All the newly created objects are stored here
Order It’s accessed using Last-in First-out (LIFO) memory allocation system This memory is accessed via complex memory management techniques that include Young Generation, Old or Tenured Generation, and Permanent Generation.
Life Stack memory only exists as long as the current method is running Heap space exists as long as the application runs
Efficiency Much faster to allocate when compared to heap Slower to allocate when compared to stack
Allocation/Deallocation This Memory is automatically allocated and deallocated when a method is called and returned, respectively Heap space is allocated when new objects are created and deallocated by Gargabe Collector when they’re no longer referenced

6. Conclusion

6.结论

Stack and heap are two ways in which Java allocates memory. In this article, we learned how they work, and when to use them for developing better Java programs.

堆栈和堆是Java分配内存的两种方式。在这篇文章中,我们了解了它们的工作原理,以及何时使用它们来开发更好的Java程序。

To learn more about Memory Management in Java, have a look at this article here. We also touched on the JVM Garbage Collector, which is discussed briefly over in this article.

要了解有关Java中内存管理的更多信息,请看这篇文章。我们还谈到了JVM垃圾收集器,在这篇文章中简要地讨论了这个问题