Java相关 - 第一篇

118 阅读3分钟
1. JVM中的 运行时内存区域 结构

方法区和堆是所有线程共享;PC寄存器,Java方法栈,本地方法栈是每个线程私有.

  1. 方法区

    1. 方法区Method Area是各个线程共享的内存区域,必须保证线程安全

      如两个类要同时加载1个尚未被加载的类C,1个类会请求ClassLoader去加载类C,另1个类只能等待C加载完成而不会重复加载

    2. 方法区存储已被加载的类的信息,常量,静态变量,即时编译器编译后的代码等.

    1. 堆是JVM管理的内存中最大的一块,被所有线程共享,在JVM启动时创建,非线程安全.
    2. 堆存在的目的就是为了存放对象实例.
    3. 堆是垃圾收集器管理的主要区域.从内存回收的角度看,现在的垃圾收集器都基于分代回收算法,Java堆可以进一步细分.
  2. PC寄存器/程序计数器

    1. PC寄存器是一块较小的内存空间,用于记录当前线程正在执行的虚拟机字节码的地址;
    2. Java虚拟机的多线程是通过线程轮流切换分配处理器执行时间来实现,在任何1个确定时刻,一个CPU/多核CPU中的1个核只能执行1条线程的指令.
    3. 当有多个线程交叉执行时,被中断的线程当前执行到哪个字节码内存地址必然要保存下来,以便用于被中断的线程恢复执行时继续执行.每个线程都有一个独立的PC寄存器,多线程之间互不影响.
  3. Java方法栈

    1. Java方法栈是线程私有的,所以不需要关心数据一致性,也不存在同步锁问题.

    2. 每当创建1个线程,JVM就会为其创建对应的Java方法栈.

    3. Java方法栈中包含多个栈帧.

      1. 每个栈帧关联了1个Java方法,每运行1个方法,就创建1个栈帧,栈帧包含了关联方法的信息.
      2. 每当1个方法执行完毕,该栈帧就会弹出栈帧的元素作为方法的返回值,并清理栈帧.Java方法栈的栈顶就是当前正在执行的方法,PC寄存器记录的也是这个地址.
      3. Java方法栈的栈顶的栈帧A调用新方法,会创建新的对应栈帧B压入栈顶,B执行完毕后,B被移除,B的返回值作为A的1个操作数,继续执行A
    4. JVM规范规定了Java方法栈中的2中异常

      1. 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常
      2. 如果虚拟机可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常
  4. 本地方法栈/Native Method Stack

    1. 本地方法栈Java方法栈所发挥的作用是非常相似的,其区别不过是Java方法栈为虚拟机执行Java方法服务,而本地方法栈则是为虚拟机使用到的Native方法服务
    2. 本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常