java中堆和栈的区别
网站首页 文章专栏 java中堆和栈的区别
java中堆和栈的区别
编辑时间:2019-05-06 18:09 作者:毛毛小妖 浏览量:116 评论数:0

    在java语言中,堆和栈都是内存中存放数据的地方,那么他们究竟有啥区别呢。

一、Java中的数据类型 

    在分析他们的区别之前,我们先来了解一下Java中的数据类型,我们知道java中数据类型分为基本数据类型和引用数据类型。基本类型有8中,分别是:boolean,char,byte,short,int,long,float,double;而引用类型就是那些可以通过 new 来创建对象的类型(基本上都是派生自 Object)。

二、堆和栈存储的东西

    具体而言,栈内存主要存放基本数据类型。栈内存的管理是通过压栈和弹栈操作来完成的,以栈帧为基本单位来管理程序的调用关系。每当有函数调用时,都会通过压栈方式创建新的栈帧,当函数调用结束后都会通过弹栈方式释放栈帧。堆内存主要用来存放运行时创建的对象,也就是通过new关键字创建出来的对象。

    堆相对进程来说是全局的,能够被所有线程访问;而栈是线程局部的,只能本线程访问。打个比方,栈就好比个人小金库,堆就好比国库。你从个人小金库拿钱去花,不需要办什么手续,拿了就花,但是钱数有限;而国库里面的钱虽然很多,但是每次申请花钱要打报告、盖图章、办 N 多手续,耗时又费力。

三、为啥要这样设计

可能有小伙伴要问了,干嘛把两种类型分开存储,干嘛不放到一起呢?这就要从很久之前说起啦,当年 Java 它爹(James Gosling)设计语言的时候,对于这个问题有点进退两难。如果把各种东东都放置到栈中,显然不现实,一来栈是线程私有的(不便于共享),二来栈的大小是有限的,三来栈的结构也间接限制了它的用途。那为啥不把各种东东都放置到堆里面呢?都放堆里面,倒是能绕过上述问题,但是刚才也提到了,申请堆内存要办很多手续,太繁琐。左思右想之后,Java 它爹只好做了一个折中:把类型分为“基本类型”和“引用类型”,两者使用不同的创建方式。这种差异从 Java 语法上也可以看出来:引用类型总是用 new 创建对象(某些单键对象/单例对象,表面上没用 new,但是在 getInstance() 内部也还是用 new 创建的);而基本类型则【不需要】用 new 来创建。

四、举个栗子

class Rectangle{
    private int width;
    private int height;

    public Rectangle{
        this.width=width;
        this.height=height;
    }
}

public class Test{
    public static void main(String[] args){
        int i=1;
        Rectangle r = new Rectangle(3,5);
    }
}

在上述程序进入main()方法后,数据的存储关系如图所示:

由于i为基本数据类型的局部变量,因此他存储在栈空间中,而r为对象的引用变量,因此也存储在栈空间中;实际的对象存储在堆空间中。当main()方法退出后,存储在栈中的i和r通过压栈和弹栈操作在栈中被回收。而存储在堆中的对象将由垃圾回收机制自动回收。

五、总结

总的来说,栈是用来存放基本数据类型和对象的引用的,堆是用来存放对象的。

推荐文章
来说两句吧
最新评论
    还没有人评论哦,快来坐沙发吧!