Java Heap Memory vs Stack Memory Difference(java Heap与Stack的区别)

原文:http://www.journaldev.com/4098/java-heap-memory-vs-stack-memory-difference


      之前我写了一些关于java垃圾回收机制以及值传递的文章。然后我收到了很多邮件要求我解释java中Heap与Stack的区别。你能找到一大堆关于java中Heap与Stack的java书籍,但是基本上没有从程序角度解释heap与stack。

Java Heap Memory
     Heap用于java运行时分配内存以及JREclasses。我们一旦创建一个对象,它总是在Heap中创建的。
GC(垃圾回收器)总是会回收不在被对象引用的内存。Heap中创建的对象具有全局访问性,即可被应用的所有类访问。(Heap是java中通过new关键字创建的对象所分配的空间)

Java Stack Memory
     Stack是某个线程执行时的变量及数据的存储空间。它存放了某个方法的临时变量以及对Heap中对象的引用变量。Stack总是LIFO(last in first out,后进先出)。当一个方法被调用,在Stack就会为此开辟一片空间用来存储变量和对象的引用。一旦这个方法结束,当前的内存空间就会被回收并为下一个方法使用。

   Stack的内存空间相较于Heap来说比较小。

   让我们通过一个简单的程序来了解Heap和Stack吧。

 Memory.java

package com.journaldev.test;
 
public class Memory {
 
    public static void main(String[] args) { // Line 1
        int i=1; // Line 2
        Object obj = new Object(); // Line 3
        Memory mem = new Memory(); // Line 4
        mem.foo(obj); // Line 5
    } // Line 9
 
    private void foo(Object param) { // Line 6
        String str = param.toString(); //// Line 7
        System.out.println(str);
    } // Line 8
 
}


Java Heap Memory vs Stack Memory Difference(java Heap与Stack的区别)_第1张图片

让我们过一遍这个程序的执行过程吧

  • 一旦我们运行程序,java虚拟机将所有的运行时类加载到Heap中。当虚拟机发现第一行的main()方法是,java运行时建立一快Stack内存空间用来给main()方法所对应线程使用。
  • 第二行我们建了一个int的临时变量。在stack分配内存并存储这个临时变量。
  • 由于我们在第三行建了一个对象,Heap为它分配存储空间,并在Stack中保存一个对它的引用。相似的处理过程发生在第四行,我们建立了一个Memory对象。
  • 当我们在第五行调用foo()方法的时候,将在stack顶层分配一块空间用来存放该方法的临时变量、引用。由于java是值传递模式,在第六行将会在stack中创建一个对象的引用。
  • 第七行建了一个字符串,它被存放在Heap中的String Pool(http://www.journaldev.com/797/what-is-java-string-pool字符串池)中。并在stack中创建一个对该字符串的引用。
  • 第八行,foo()方法调用结束,stack中为它开辟的内存空间将会被释放。
  • 第九行,main方法结束,stack中为main方法开辟的内存也将会被释放。同时,程序也在此行结束。因此java虚拟机将会释放所有的内存以及结束这个程序。


 Heap与Stack的主要区别
 
 基于以上说明,我们能够轻易的得出以下结论
 
 1、Heap作为这个应用的共享内存。而stack仅仅是被某个执行线程所使用。
 2、当通过new创建一个对象的时候,他总是会被存放在Heap中,并且stack中会保存一个对该对象的引用。Stack仅仅保存临时变量以及Heap中对象的引用。
 3、存储在Heap中的对象是全局可访问的,然而stack只能被特定线程访问。
 4、stack中的内存管理模式是LIFO(last in first out)然而heap的内存管理模式更加复杂,因为它作为共享数据区域。Heap内存空间分为年轻代(Young-Generation)和老代(Old-Generation),详情参考Java Garbage Collection.
 5、Stack中数据生存周期是固定的。heap数据的生存周期是直至程序结束的。
 6、我们可以通过-Xms、-Xmx选项来设置jvm的heap内存,-Xss定义stack内存大小。
 7、当stack内存耗尽的时候会抛出java.lang.StackOverFlowError
     heap会抛出java.lang.OutOfMemoryError: Java Heap Space error
8、stack相较于heap内存空间比较小。由于内存分配策略LIFO,stack的存储速度会比heap快。

以上是关于在java应用的角度heap与stack的分析


补充:

JAVA的内存模型及结构

http://ifeve.com/under-the-hood-runtime-data-areas-javas-memory-model/




你可能感兴趣的:(java,堆栈,stack,heap)