Java虚拟机之堆 VS 栈

1、堆

Java堆是用来在运行时给Java对象(Objects)和JRE 类分配内存空间的。
垃圾收集器就是收集堆中没有被引用到的对象。对应用程序来讲,堆是全局的,它可以在应用的任何地方被引用到。

2、栈

java栈内存用于一个线程执行。他们包含了方法中局部变量的值和堆中对象的引用。

栈内存是后进先出(LIFO)顺序的。当一个方法被调用时,就为它分配一块栈空间用于保存方法中的局部变量值和引用。当一个方法调用结束时,那这块栈空间就没用了,他就分配给下一个方法使用了。

栈内存的大小相对于堆内存是非常小的。

3、Java程序中的堆和栈

用一个实际例子来理解堆内存和栈内存的用法。

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

}

下面这张图显示了堆和栈的引用情况,以及他们是如何存储局部变量、对象和对象的引用的。
这里写图片描述
我们看下程序的执行步骤:

  1. 当程序开始执行时,虚拟机就把所有的运行时类加载到堆内存中;当发现Line 1的main() 方法时,Java 运行时就创建栈空间,用来分配给当前线程的main()方法来使用。
  2. Line 2 创建了一个局部变量,它被存储到 main() 的栈内存中。
  3. Line 3 创建了一个Java 对象,它被存储到堆内存中。
  4. 当Line 5 中的 foo( ) 方法被调用时,就在栈顶为其创建一块内存。由于java是按值传递的,所以在Line 6, 在foo() 的栈内存中为参数对象创建了一个新的引用。
  5. Line 7 创建了一个 String,他被存放到 String Pool中,同时在 foo() 的栈内存中为其创建了一个引用。
  6. Line 8 中,foo() 方法执行结束了,这时,为其分配的栈内存就变得空闲了。
  7. Line 9 中,main() 执行结束了,这时为其分配的栈内存就被销毁了。同时,程序也结束了,因此,java运行时释放所有内存和结束程序的执行。

4、堆和栈的不同点

基于以上的解释说明,我们可以很容易地总结出如下的不同点:

  1. 堆是全局的,在应用的各个部分中都会用到;栈是线程私有的,是用来给线程执行的。
  2. 堆是用来存储对象的,栈是用来存储堆中对象的引用和局部变量的。
  3. 堆中存储的对象是全局可访问的,而栈内存不能被其他线程访问。
  4. 栈内存的管理是后进先出(LIFO)的,而堆内存更复杂,因为它是全局的。他被划分为年轻带,老年代等。
  5. 栈内存是短生命周期(short-lived )的,而堆内存的生命周期是从应用开始执行到应用结束。
  6. 可以使用 -Xms 和 -Xmx JVM参数来设置堆内存的起始大小和最大值。 可以使用 -Xss 来定义栈内存的大小。
  7. 当栈内存用满时,Java 运行时会抛出 java.lang.StackOverFlowError ;而堆用满时,会抛出java.lang.OutOfMemoryError: Java Heap Space 错误。
  8. 栈内存大小相比于堆内存的大小,它是非常小的;堆栈内存与堆内存相比非常快。

参考:
Java Heap Space vs Stack – Memory Allocation in Java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值