侧边栏壁纸
博主头像
ZHD的小窝博主等级

行动起来,活在当下

  • 累计撰写 79 篇文章
  • 累计创建 53 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

JVM内存模型

江南的风
2017-06-30 / 0 评论 / 0 点赞 / 21 阅读 / 5473 字 / 正在检测是否收录...

JVM(Java Virtual Machine,Java虚拟机)内存模型是Java程序在运行时进行内存分配和管理的核心机制。它定义了Java虚拟机在执行Java程序时,将程序中的数据和代码存储到计算机内存中的方式和规则。JVM内存模型的主要组成部分包括堆(Heap)、方法区(Method Area)、程序计数器(Program Counter Register)、虚拟机栈(VM Stack)和本地方法栈(Native Method Stack)。

以下是对这些组成部分的详细解释:

1. 堆(Heap)

  • 定义:堆是JVM管理的最大的一块内存区域,用于存储对象实例和数组。

  • 特点

    • 堆区是线程共享的,所有线程都可以访问堆中的数据。

    • 堆内存的大小可以通过启动参数(如-Xmx-Xms)来调整。

    • 堆内存区域按照垃圾分代收集的角度可以进一步划分为年轻代(Young Generation)和老年代(Old Generation),默认年轻代和老年代比例为1:2。年轻代又可以分为Eden区From Survivor区To Survivor区,默认比例为8:1:1。

    • 当堆中没有足够的内存完成实例分配时,并且堆也无法再扩展时,JVM会抛出OutOfMemoryError异常。

  • 调整大小:年轻代与老年代默认为1:2,可通过-XX:NewRatio参数修改,如-XX:NewRatio=4,即为1:4。

    伊甸区和S0、S1区默认为8:1:1,可通过-XX:SurvivorRatio参数修改,如-XX:SurvivorRatio=6,通过监测发现设置,以后并不是6:1:1,这是因为Java堆的内存分配策略自动调整了,关闭内存分配策略:-XX:-UseAdaptiveSizePolicy。

2. 方法区(Method Area)

  • 定义:方法区用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。其中静态变量,JDK7以后移入Java堆中,字符串常量池(JDK8移入Java堆中。

  • 特点

    • 方法区也是线程共享的

    • 在JDK 8之前,方法区通常被称为永久代(PermGen space),但在JDK 8及以后版本中,永久代被元空间(Metaspace)所取代。

    • 方法区的大小可以通过启动参数(如-XX:MaxMetaspaceSize)来设置。

    • 当方法区无法满足新的内存分配需求时,JVM会抛出OutOfMemoryError异常。

  • 调整大小

    • 永久代(JDK1.7)

      -XX:PermSize : 永久代初始化内存,默认20.75M, -XX:PermSize=20m

      -XX:MaxPermSize: 永久代最大内存,32位虚拟机默认64M, 64位默认82M,超出时会报java.lang.OutOfMemoryError:PermaGen space

    • 元空间(JDK1.8)

      -XX:MetaspaceSize:元空间初始化内存,默认是21M

      -XX:MaxMetaspaceSize:元空间最大内存,默认是-1无限制。虽然使用直接内存,但是当无法再为Metaspace分配内存时,将会抛出java.lang.OutOfMemoryError: Metaspace

3. 程序计数器(Program Counter Register)

  • 定义:程序计数器是线程私有的,用于存储线程当前执行的字节码指令的地址。分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖程序计数器完成。

  • 特点

    • 程序计数器是唯一一个在《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域。

    • 它记录了线程执行的字节码指令的偏移量,是线程恢复执行时的重要信息。

4. 虚拟机栈(VM Stack)

  • 定义:虚拟机栈是线程私有的,用于存储局部变量表、操作数栈、动态连接、方法出口等信息。

  • 特点

    • 每个方法被调用时,JVM都会同步创建一个栈帧(Stack Frame)用于存储这些信息。

    • 栈帧的入栈和出栈过程对应着方法的调用和返回。

    • 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈容量可以动态扩展但无法申请到足够的内存,将抛出OutOfMemoryError异常。

  • 调整大小:虚拟栈的大小可以通过-Xss参数设置,默认单位是byte,也可以使用不区分大小写k,m,g作为单位(如-Xss1m)。

5. 本地方法栈(Native Method Stack)

  • 定义:本地方法栈与虚拟机栈的作用非常相似,但它是为虚拟机使用到的本地(Native)方法服务。

  • 特点

    • 本地方法栈也是线程私有的

    • 它与虚拟机栈的区别在于服务的对象不同:虚拟机栈为虚拟机执行Java方法(即字节码)服务,而本地方法栈则为虚拟机使用到的本地方法服务。

    • 本地方法栈同样会抛出StackOverflowError和OutOfMemoryError异常。

综上所述,JVM内存模型通过堆、方法区、程序计数器、虚拟机栈和本地方法栈等组成部分,为Java程序提供了高效、灵活的内存管理机制。这些组成部分各有其特点和作用,共同保障了Java程序的稳定运行。

0

评论区