java内存区域

运行时候的区域

  • Java虚拟机在执行程序的时候将它所管理内存区域划分为若干数据区域,这些区域各有用途,创建时间和销毁时间等都不同。

程序计数器

  • 程序计数器是一块较小内存的空间,可以看做当前线程所执行的字节码行号指示器。java虚拟机的多线程是通过线程轮流切换并分配处理执行时间的方式来实现的,任何时刻,一个处理器都会执行一个线程的指令。因此为了切换后能够恢复到正确的执行位置,每个线程独有一个程序计数器,线程独立存储,互不影响,被称作“线程私有”内存。

  • 线程执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行时native方法,计数器为空。此区域是唯一一个没有OutOfMemeoryError情况的区域。

java虚拟机栈

  • java虚拟机栈也是线程私有的,和线程生命周期相同。
  • 描述的是java方法执行的内存模型:每个方法执行的时候都会创建一个栈帧用来存储局部变量表、操作数栈、动态链接、方法出口信息,每个方法从调用到直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈道出栈的过程。
  • 如果请求的栈的深度超过了虚拟机最大的深度,会抛出StackOverFlowError异常
  • 如果扩展时候无法申请到足够的内存,就会抛出OutOfMemoryError异常。

    本地方法栈

  • 虚拟栈为虚拟机执行java方法服务,本地方法栈 则为虚拟机使用到的native方法服务。
  • 本地方法栈也会抛出StackOverFlowError和OutOfMemoryError异常。

Java堆

  • java堆是虚拟机管理的内存最大的一块,是所有的线程共享的区域,此内存唯一目的就是存放对象实例。
  • java堆是垃圾收集器管理的主要区域,因此被称为GC堆,由于收集器都采用分代收集算法,所以堆可以分为:新生代、老年代。

方法区

  • 方法区和java堆一样是各个线程共享区域,用户存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
  • 更多的人把方法区成为”永久代”,但是两者并不等价,仅仅是因为Hotspot虚拟机设计团队选择吧GC分代扩展至方法区,或者使用永久代来实现方法区而已。