我所认识的java栈和堆
堆和栈是什么?从哪儿来的?
首先,附上一张图片,展示一下JVM运行时的数据区有哪几类
从图中可以看出,在JVM运行时,数据区有5类:JVM栈、本地方法栈、程序计数器、堆、方法区
可以看到,有两类栈:JVM栈和本地方法栈,我们这里说的栈主要针对的是JVM栈
栈和堆是用来干什么的?
栈:
- 用于存放局部变量
- 用于存放基本数据类型(int,float,double等)
- 用于存放对象的引用(也就是指向对象的地址)
堆:
- 存放new 出来的对象和数组 【PS. 这里额外说一下,如果new 一个对象时,堆内存中没有足够的空间来满足对象的创建,JVM就会抛出OutOfMemoryError错误】
- 存放类变量(static 修饰的变量)
我俩有啥不一样呢?(堆和栈的区别)
- 通俗的来说:堆主要是用来存放对象的,栈主要是用来执行程序的。
- 空间大小方面:堆的空间要远大于栈的空间
- 数据的存储速度方面:栈的速度要比堆快
- 线程共享方面:堆是可以被线程共享的;但是栈确实线程私有的,每个线程都有自己单独的栈空间
- 数据共享方面:存放在栈中的数据是可以共享的
int a = 6;
int b = 6;
/**
在执行这两条语句时,编译器在首先会处理int a = 6;会在栈中创建一个变量为a的引用,然后查找栈中
是否有6这个值,如果没有找到,则将6存放进来,然后将a指向6;接下来处理int b = 6语句,会在栈中
创建一个变量为b的引用,因为之前栈中已经有了6变量,所以直接将b指向原先的6。这时,a和b同时指向
同一个值6。如果还有一条语句将b重新赋值b=8,那么还会判断栈中是否有8这个值,如果有的话就直接将b
指向8,如果没有的话就将8存放到栈中。
【注意这种数据共享和两个对象的引用指向同一个对象的这种共享是不一样的,前者一个值的改变不影响另外
一个值,后者则会影响。】
**/
- 垃圾回收机制不一样:
局部变量方法执行完毕后,改变量占用的栈内存空间就会被回收;
堆内存的数据是使用GC机制来回收的 - 内存大小的分配不一样:堆可以动态地分配内存大小;栈中的数据大小是确定的。
- 生存期不一样:堆因为是动态分配地,所以不需要事先告诉编译器其生存期;栈中的数据生存期是确定的。
写此博客时学习了其他博主的博客,这里列举出来,如有遗漏,还请告知。
[1]: https://blog.csdn.net/zhangqiluGrubby/article/details/59110906
[2]: https://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html