栈和内存都是放数据的地方,但是两个存放的数据类型不一样。栈是为执行线程留出的内存空间,堆是为动态分配预留的内存空间,每一个线程都有一个栈,但是每一个应用程序只有一个堆
堆内存:存放new创建的对象和数组,存储实例,如再函数里声明一个类的变量:A a,那么这个a时存储在栈内存中,注意:是在栈内存中,实例化后 a = new A(),实例后的对象是在存在堆内存中,栈内存中存储的a指向堆内存的地址指向,堆内存的存在是为了更好的管理内存,当a不再指向堆内存的实例时,就会把堆内存中的new A()实例删除,释放内存。
栈内存:存放基本数据类型变量,对象的引用变量,局部变量还是成员变量,基本类型包括:(int,short,long,byte,float,double,boolean,char) ,另外也存储函数的主体和变量名,java的代码是在函数体中执行的,每个函数主体都会被放在栈内存中,如main函数,假如main函数里调用了其他的函数,比如:update(),那么栈里面的存储就是最底层是main,main上面是add,栈的运行是后入先出,所以执行时会先销毁update,再销毁main
静态区/方法区:存放全局变量和静态变量 class文件和静态数据 线程共享
对比:
栈:
1.存储在计算机RAM中
2.在栈创建变量的时候会扩展,并且会自动回收
3.相比堆而言栈上分配要快的多
4.用数据结构的栈实现
5.存储局部数据,返回地址,用做参数传递
6.当用栈过多时可导致栈溢出(无穷次(大量的)的递归调用,或者大量的内存分配)
7.在栈上的数据可以直接访问(不是非要使用指针访问)
8.编译之前精确的知道需要分配数据的大小并且不是太大的时候,可以使用栈
9.当程序启动时决定栈的内容上限
10.栈中的新加数据项放在其他数据的顶部,移除时也只能移除最顶部的数据
堆:
1.存储在计算机RAM
2.变量必须手动释放,不存在作用域的问题,数据可用delete,delete[]或者free来释放
3.相比在栈上分配内存要慢
4.通过程序按需分配
5.大量的分配和释放可造成内存碎片
6.在c++中,在堆上创建数据使用指针访问,用new或者malloc分配内存
7.如果申请的缓冲区过大,可能申请失败
8.在运行期间不知道需要多大的数据或者需要分配大量的内存的时候,建议使用堆
9.可能造成内存泄露
10.数据项位置没有固定的顺序,可以任何顺序插入和删除(堆的特点乱嘛)
堆中分配的内存,有java虚拟机的自动垃圾回收器来管理
竟然知道了栈和堆的特性,那么为什么要设计栈和堆呢?
个人理解有2:
首先栈是存放对象的引用,就是指向对象的地址
1.栈的存取速度快,当程序要在内存读写数据时,先找到栈,在通过栈的指向到堆内存进行数据的读写,这样不用遍历速度慢而且数据多的堆。
2.便于内存的回收,当程序的一些数据不用之后,就会释放空间,那么这个堆内存空间没有栈的指向,这样java虚拟机的垃圾回收机制就会将这块空间回收。