栈(Stack),堆(heap),静态区(static area)的用法

  • Post author:
  • Post category:其他




Heap区:主要用来保存对象的实例(new创建的对象和数组),实际上也只是存储对象实例的属性值(属性),属性的类型和对象本身的类型标记等,

  • 并不保存对象的方法(方法是指令,保存在stack中)
  1. heap存储的全部是对象 ,每个对象包含一个与之对应的class信息(class的目的是得到操作的指令(指令也就是方法))
  2. jvm只有一个heap区,被所有的线程共享,heap中不存储基本的数据类型,只存储对象本身
  3. 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收



stack区:对象在heap中分配好以后,需要在stack中保存一个4个字节的heap内存地址,用来定位该对象实例在heap中的位置,便于找到该实例对象

  1. 每个线程都有一个stack区,stack中只保存基本数据类型的对象和自定义的对象引用(也就是地址值),对象都存储在heap中
  2. 每个stack中的数据(原始的基本数据类型和对象的引用)都是private的,其他的stack不能访问
  3. stack分为3个部分:基本数据类型变量区,执行环境上下文,操作指令区(存放操作指令)
  4. 由编译器自动分配释放,存放函数的参数值,局部变量的值等



静态区/方法区:

  1. 方法区也是静态区,和heap一样,被所有的线程共享,方法区包含所有的class和static变量.
  2. 方法区中包含的都是整个程序中永远唯一的元素,如class,static变量
  3. 全局变量和静态变量的存储都是放在一块的,初始化的全局变量和静态变量在一块,没有初始化的再另外一块区域


注意:
  • stack是运行的基本单位,在stack中一个对象只对应4个字节的引用地址
  • heap是存储的基本单位,在heap中对象的大小是不确定的,动态变化的



为何把stack和heap分离开

  1. 在软件设计的角度:stack代表了处理逻辑,heap代表了数据,这样分而治之
  2. stack和heap的分离,这样heap中的数据可以被更多的线程共享,一方面提供了数据交互的方式,二方面共享常量和缓存可以被多个线程访问,节省空间
  3. stack是向上增长的,因此限制了存储的能力,但是heap是动态增长的,stack和heap分离,让动态增长成为可能,相应的stack中只需要记录对应的地址
  4. 面向对象就是stack和heap的完美结合
  • 对象的属性其实就是数据存储在heap中
  • 对象的操作也就是方法(指令)存储在stack中