其实,堆区和栈区从本质上讲没有任何区别,因为它们都是内存的一块区域而已。
它们的区别在于用法。
在我们的代码中,会使用各种各样的变量,而这些变量是会占据内存的,也就涉及到了内存的分配与释放。
当变量出现时,就会产生一个问题:这些变量的使用范围(生命周期)是仅仅局限在一个函数内部还是超越函数?如果是局限在一个函数内部,那么当这个函数执行完后,这个变量占据的内存就可以释放了,这种变量也就是所谓的局部变量。
对于局部变量占据的内存其实非常好管理,内存的分配和释放仅仅只需要移动一个指针(寄存器)就可以实现了,至于为什么,看我接下来如何解释的。
func调用func1,func1调用func2。当执行到func时,在内存中占据一定内存(图中标记func),执行func1和func2同理。而func2执行完成之后,func2的内存就可以释放,指针(寄存器)指向下一个(func1),后面依次类推。总体来看,就是先分配的后释放。发现没有,这和“栈”的概念简直一模一样!所以叫做栈区。
接下来我们再来看看堆区。如果一个变量的生命周期超越了函数,那么当函数运行完成之后,这个变量占据的内存是不会被释放的。
那么变量在堆区占据的内存是怎么释放的?
如果像是C语言,就需要程序员自己释放。在Java中,可以等待JVM收取垃圾。
当我们搞明白堆区和栈区的区别,那你知道基本类型和包装类型的区别吗?
其实,在我们实际开发中,除了定义一些常量和局部变量之外,我们在其他地方比如方法参数、对象属性中很少会使用基本类型来定义变量。并且,包装类型可用于泛型,而基本类型不可以。
对于基本数据类型,如果是局部变量,会存放在栈中;如果是全局变量,会存放在堆中。
对于包装类型,因为包装类型本质上都是对象,所以它们都存放在堆中。
它们在以下三点上有明显区别:
1.占用空间不同:相比于包装类型,基本数据类型占用的空间很小。
2.默认值不同:包装类型不赋值默认为null,而基本数据类型有默认值不为null。
3.比较方式不同:对于基本数据类型来说,==比较的是值;对于包装类型来说,==比较的是对象的内存地址。所有整型包装类对象之间值的比较,全部使用equals()方法。
标签:栈区,释放,Java,变量,包装,堆区,内存,类型 From: https://blog.csdn.net/m0_75276797/article/details/144459882