内存中的栈、堆和静态区的用法

本周的第三篇博客,这个题目应该也是老生常谈的问题。

1 堆区

先了解下Heap的作用,堆区是专门用来存储对象的实例的,也就是我们平时通过new出来的对象,但是实际上这里面也只是保存了对象实例的属性值,属性的类型和对象本身的标记等一些内容,其中值得注意的是它里面并不保存对象的方法(方法也可以理解成指令,保存在stack中)

所以我们加以总结和延伸下:

1 它存储的都是对象,而且每个对象都包含一个与之对应的class的信息。这样做的目的是能够让对象得到操作的指令集。

2 需要注意的是JVM中只有一块堆区(Heap),而且它是被所有线程共享的。堆区中存放的只有对象本身,不存放基本数据类型和对象的引用。

3 关于堆区的分配和释放一般是由程序员做这个操作。其实这一点很好理解,程序员new一个对象相当于对这块区域做了分配的工作,而当程序员做delete操作时,相当于释放了这部分空间,同时如果程序员的习惯不好,不对无用的对象进行释放的话,当程序结束时,也会由OS做这个工作。

2 栈

然后我们再了解下Stack的作用,当我们在堆区中为我们new出来的对象分配好空间之后,我们需要在栈中保存一个4字节的Heap的地址,用来定位该对象实例在Heap中的位置,便于找到该对象实例。

其实Stack的功能不止于此:

1 不同于Heap,Stack的个数是和线程挂钩的,每个线程都包含一个Stack,而且栈中只包含了基本的数据类型的变量和对象的引用。

2 栈之间是相互独立的,所以栈中的数据都是私有的,其他的栈不能访问。

3 栈可以分为三个部分:基本数据类型变量区、执行环境的上下文、操作指令区

4 栈相对于堆区,它的分配和释放的工作是系统自己做的

3 静态区/方法区

类似于堆区,而且是被所有线程所共享的。方法区中存放了整个程序中所有的永远唯一的变量,例如:class信息和static变量等。

它也是分了三块:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

注意

栈是运行时的单位,而堆是存储时的单位

值得注意的是:堆和栈不都可以存储数据吗,为什么要将这两者区分开来?

** 1 ** 首先从软件设计的角度来看这个问题,栈其实代表了处理逻辑,而堆代表了数据存储。这种分而治之的思想,使得我们的处理逻辑更为清晰。

** 2 ** 因为堆是共享的,所以堆中的内容也是被多个栈共享的。这样做的收益有两个方面:一方面这种共享提供了一种有效的数据交互方式,另一方面,堆中的共享常量和缓存可以被所有的栈访问到。

以上。感谢驻足~