对堆、栈在不同场景的理解

最近学Java的时候,在书中经常看到某部分存储到什么地方,内存是怎么分配的以及堆栈等问题;然后,想起以前学数据结构的时候,内存中也学到了数据的存储,讲到了堆和栈,操作系统中,也是有堆和栈这个概念的,这个确实让我非常混淆,今天好好整理下,也参考了很多资料,总结下,这个堆栈在各个情况下的理解。

1. JVM就是基于堆栈的虚拟机,JVM为每个新创建的线程都分配了一个堆栈,对于一个java程序而言,它的运行就是通过堆栈的操作来完成的。在Java中,内存分为堆内存和栈内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配;而由new创建的对象和数组存放于堆内存中。在栈内存中,java为变量分配内存空间,同时java也会自动释放掉为该变量分配的内存空间,在对内存中,java虚拟机自动垃圾回收器来管理堆中分配的内存。栈有一个很重要的特殊性,就是存在栈中的数据可以共享。比如我们同时定义:int a=3; int b=3;编译器先处理int a =3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没有找到,就将3存放进来,然后a指向3;接着处理int b=3,在创建b的引用变量后,因为栈中已经有3这个值了,便将b直接指向3。这样,就出现了a和b同时都指向3的情况。这时,如果另a=4,那么编译器会重新搜索栈中是否有4,如果没有,则将4存进来,并令a指向4,如果有了,则将a指向这个地址。因此a的值改变不会影响到b的值,要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的。因为这种情况a的修改并不会影响到b,这是编译器完成的。在堆中,存放的对象,其实,我么Book novel=new Book()的时候,其中novel这个引用变量时存放在栈内存中的,然后指向对象在堆中的地址。为什么在堆中存放对象或者数组,这是因为对象和数组所需的存储空间只有在运行时创建了对象之后才能确定的,堆具有这种灵活性。同时,堆是由垃圾回收来负责的,它的优势就是可以动态的分配内存的大小,生存期也不必事先告诉编译器。栈的优势就是存取速度快,仅次于寄存器,栈数据可以共享。存在栈中的数据大小与生存期必须是确定的,所以存放一些基本的数据类型。

2、在C/C++中,与在操作系统中一样,栈区是由编译器自动分配和释放的,存放函数的参数值、局部变量的值等。其操作方法类似于数据结构中的栈,先进后出;堆区一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。这里的堆与数据结构的堆又是不一样的,这里的堆类似于链表。3、在数据结构中,栈就是一种先进后出,后进先出的数据结构,和队列是相反的;而堆通常是一个可以被看做一棵树的数组对象。堆总是一棵完全树,即除了最底层,其它层的结点都被元素填满,根结点最大的堆叫做最大堆或者大根堆。

猜你喜欢

转载自blog.csdn.net/u014430055/article/details/52938374