Java中的堆和栈有啥区别

在java语言中,堆与栈都是内存中存放数据的地方,变量分为基本数据类型和引用类型,基本数据类型的变量(列如,int,short,long,byte,float,double,boolean以及char等)以及对象的引用变量,其内存都分配在栈上,变量出了作用域就会自动释放,而引用类型的变量,其内存分配在堆上或者常量池(列如字符串常量和基本数据类型常量)中,需要通过new等方式创建。

具体而言,栈内存主要用来存放基本数据类型与引用变量,栈内存的管理是通过压栈和弹栈操作来完成的,以栈帧为基本单位来管理程序的调用关系,每当有函数调用时,都会通过压栈方式创建新的栈帧,每当函数调用结束后都会通过弹栈的方式释放栈帧。

堆内存用来存放运行时创建的对象,一般来讲,通过new关键字创建出来的对象都存放在堆内存中,由于JVM是基于堆栈的虚拟机,而每个java程序都运行在一个单独的jvm实列上,每一个实列唯一对应一个堆,一个java程序内的多个线程也就运行在同一个jvm实列上,因此这些线程之间会共享堆内存,鉴于此,多线程在访问堆中的数据时需要对数据进行同步,

在C++中,堆内存的管理都是由开发人员来负责的,也就是说,开发人员在堆中申请的内存,当不在使用时,必须由开发人员完成堆内存的释放工作,而在java语言中,这个内存释放的工作由垃圾回收器来负责执行,开发人员只需要申请所需的堆空间而不需要考虑释放的问题。

在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象,这就是java中引用的用法。

从堆和栈的功能以及作用来比较,堆主要用来存放对象的,栈主要是用来执行程序的,相较于堆,栈的存取速度更快,但栈的大小和生存期必须是确定的,因此缺乏一定的灵活性,而堆却可以在运行时动态的分配内存,生存期不用提前告诉编译器,但这也导致了其存取速度的缓慢,

我们来用代码演练一下

public class Student {
    //名字
    private String name;

    //年龄
    private int age;

    public Student(){}

    public Student(String name,int age){
           this.name = name;
           this.age = age;
    }

    public static void main(String[] args) {
        int i= 1;
        Student student = new Student("李思思",25);
    }
}

在上述程序进入mian()方法后,数据的存取关系如图

由于i为基本数据类型的局部变量,因此它存储在栈空间中,而student为对象的引用变量,因此也被存储在

栈空间中,实际的对象存储在堆空间中,当main()方法退出后,存储在栈中的i和student通过压栈和弹栈

操作将会在栈中被回收,而存储在堆中的对象将会由垃圾回收器来自动回收。

博主曾经面试的时候被面试官闻到了一个问题

栈有几个空间,堆有几个空间

我们来从多线程的角度来分析这个问题,首先栈是私有的,堆是线程共享的,那么我们很容易推测出栈是多个空间,

堆只有一个空间。

上面如有不对的地方,请各位看官指教出来,小弟好改之,一起努力成长。

发布了41 篇原创文章 · 获赞 8 · 访问量 1286

猜你喜欢

转载自blog.csdn.net/sdgames/article/details/105022008