深入理解虚拟机阅读笔记-运行时数据区域

运行时数据区域

  • 程序计数器(pc寄存器)
    • 线程私有,空间较小,是当前线程所执行字节码的行号指示器
    • 字节码解释器工作时,通过改变计数器的值来取得下一条字节码指令。
    • 分支、循环、跳转、异常处理、线程恢复等操作的依赖。
    • Java方法:当前字节码指令的地址;
    • Native方法,则为空。
    • 唯一无OutOfMemoryError情况的内存区域
  • Java虚拟机栈
    • 线程私有,描述的是Java方法执行时的内存模型
    • 方法执行时创建栈帧入栈,方法执行结束出栈
    • 栈帧:用于存局部变量表、操作数栈、动态链接、方法出入口等信息
      • 局部变量表
        • 存放编译期可知的数据,内存空间在编译期完全确定,运行期间不会改变
        • 各种基本数据类型,64位长度的long和double栈两个局部变量空间 (slot),其余一个
        • 对象引用(reference类型,直接指向对象地址的指针,或者指向对象句柄)
        • returnAddress类型(指向了一条字节码指令的地址)
    • 异常情况
      • 线程请求的栈深度大于虚拟机运行深度,抛出StackOverflowError
      • 若虚拟机栈运行动态扩展,则当扩展时无法申请到足够的内存,抛出OutOfMemoryError
  • 本地方法栈
    • 与虚拟机栈类似,不过服务于Native方法
    • 异常情况与虚拟机栈相同
    • 虚拟机规范不对该区域使用的语言、方式和数据结构做强制规定,可自由实现
  • Java堆
    • 空间最大,线程共享,虚拟机启动时创建,用于存放对象实例
    • 内存空间属于物理不连续
    • Java虚拟机规范:所有的对象实例与数组都要在堆上分配
    • 无法动态扩展时,抛出OutOfMemoryError
    • 内存划分
      • young:old 默认为 1:2
      • 年轻代
        • Eden:Survivor = 8 :1
        • 存在一个Eden区域与两块Survivor
        • Eden
          • 存放的刚创建的对象,当该部分被耗尽时,就进行young gc(Minor gc)。
        • Survivor
          • 每次young gc,将eden存活的对象和另一个Survivor的对象,整理到当前servivor,保证存储自身存储空间的连续性以及另外空间的空闲。
      • 老年代
        • 默认存放着Survivor中经过了15次Minor gc的对象
        • 或者当Minor gc时,Survivor内存不足,依赖老年代做分配担保,直接将对象转移进该区域
        • 或者当对象大于一定大小,则直接在老年代分配
  • 方法区
    • 线程共享,用于存储加载的常量、静态变量、即时编译器编译后的代码等
    • 线程安全,在类加载时,只允许有一个线程去加载某个类信息到方法区
    • 永久代(1.8后移除):Hotspot把gc分代收集扩展至方法区,方便如堆一般管理内存
    • 无法满足内存分配需求时,抛出OutOfMemoryError
    • 运行时常量池
      • class文件存放编译期生成的字面量和符号引用,在类加载后存入该区域。
      • 也存放翻译出来的直接引用
      • 动态性:允许运行期将新的变量防区
      • 无法满足内存分配需求时,抛出OutOfMemoryError
  • 直接内存
    • 堆外内存,非虚拟机规范定义,不受虚拟机本身限制
    • 无垃圾回收管理
    • 1.4引入的NIO类,基于通道Channel与缓冲器Buffer的IO方式,使用Native函数直接分配堆外内存
    • 通过Java对中的DirectByteBuffer对象作为这块内存的引用进行操作。
    • 通过参数指定大小,默认与堆最大值相同
    • 分配内存时若出现内存溢出,并不是申请分配内存,而是计算出内存不足,手动抛出异常
  • 元空间
    • 存储加载的类信息
    • 元数据区取代了永久代,本质和永久代类似,都是对JVM规范中方法区的实现,区别在于元数据区并不在虚拟机中,而是使用本地内存。元数据区在频繁使用,也会发生OutOfMemory异常。
    • 元数据区的动态扩展,默认–XX:MetaspaceSize值为21MB的高水位线。一旦触及则Full GC将被触发并卸载没有用的类(类对应的类加载器不再存活),然后高水位线将会重置。新的高水位线的值取决于GC后释放的元空间。如果释放的空间少,这个高水位线则上升。如果释放空间过多,则高水位线下降。
发布了24 篇原创文章 · 获赞 0 · 访问量 107

猜你喜欢

转载自blog.csdn.net/jiangxiayouyu/article/details/105606948
今日推荐