JVM内存结构浅析

作者: RunAlgorithm | 来源:发表于2017-03-18 16:08 被阅读1568次

1 概述

具有内存动态分配和自动回收的特点

2 运行时内存

运行时内存结构

2.1 程序计数器(Program Counter Register)

特点

  • 线程私有,因为多线程并发回来后要恢复到当前线程之前执行的位置,所以每个线程都会独立拥有一个 PC
  • 占用空间极小

字节码行号指示器,解释器通过它来选取下一条执行的字节码指令

  • 执行 Java 方法:具体的内容就是指向下一个指令的偏移
  • 执行 Native 方法:计数值为空(undefined)

不会有 OutOfMemoryError

2.2 Java 虚拟机栈(Java Stack)

java stack

特点

  • 线程私有
  • 以栈帧为单位,进行压栈和出栈

结构

整个栈以栈帧为单位

  • 局部变量表(Current Variable Table)
    以变量槽(Slot)为单位,也成为
    有 this 引用,方法参数,定义的局部变量
    字节码指令使用从 0 开始索引来使用其中的数据,而 0 Slot 都默认为当前方法所属的实例的引用,即 this
    分配多大的局部变量空间在编译期间已经确定
    int,float,reference,returnAddress 占一个 Slot ;byte,short,char 会被转成 int;long,double 占两个连续 Slot

  • 操作数栈(Operand Stack)
    以变量槽(Slot)为单位
    字节码指令从操作数栈弹出数据,执行计算,再把结果入操作数栈
    操作数栈的深度在编译期已经决定,在方法的 Code 属性的 max_stacks 数据项中

  • 动态链接(Dynamic Linking)
    指向运行时常量池中栈帧所属方法的引用
    用来支持方法调用中的动态连接。常量池的方法的符号引用,一部分在类加载的时候转化为直接引用,被称为静态解析。而动态连接指的是在每一次运行期间转化为直接引用

  • 返回地址(Return Address)
    正常返回,PC技术器的值作为返回地址保存
    异常返回,通过异常处理表获得返回地址,栈帧一般不会保存这部分信息

设置虚拟机栈的大小

  • -Xss

例如:-Xss128K

有两种异常

  • StackOverflowError
  • OutOfMemoryError

2.3 本地方法栈(Native Method Stack)

线程私有

为本地方法执行 Native 方法服务

2.4 Java 堆(Heap)

Java 堆

特点:

  • 线程共享
  • 内存最大的一块
  • 目的:存放对象实例 和 数组,但随着 JIT 的发展和逃逸分析技术成熟,栈上分配、标量替换,对象实例开始不一定分配在堆上

因为是 GC 回收的主要区域,根据 GC 的实现机制,会对堆进行分代

  • 新生代(Young Generation)
    Eden 新生的对象
    Survivor Space 每次GC后还存活的对象,可再细分为 From Survivor 和 To Survivor

  • 老生代(Old Generation)
    Tenured,存放生命周期长的对象

堆内存分配由 -Xmn 来指定

  • -Xms,初始使用,默认物理内存 1/64
  • -Xmx,最大内存,默认物理内存 1/4

例如:-Xms20m -Xmx20m

虚拟机会根据堆的空闲情况动态调整推大小,空余大于 70%,会减少到 -Xms,空余小于 40%,会增大到 -Xmx

所以服务器如果配置 -Xms = -Xmx,则可以避免堆自动扩展

新生代进行 minor GC,老生代进行 major GC(深度GC)。大部分GC发生在新生代中

2.5 方法区(Method Area)

特点:

  • 线程共享
  • 又称为 Non-Heap,用来和堆进行区分
  • HotSpot 虚拟机把 GC 分代收集扩展至方法区,所以在 HotSpot 可以称它为永久代(Permanent Generation)

存储被虚拟机加载的内容有:

  • 类信息
  • 常量
  • 静态变量
  • 即时编译器编译后的代码

方法区包含运行时常量池,Class 文件的各种字面量和符号引用,在类加载后会存入到运行时常量池中。直接引用也会存储在运行时常量池。除了类加载阶段,运行时也可以动态加入,比如 String 的 intern() 方法

方法区的大小的分配

  • -XX:MaxPermSize 最大值
  • -XX:PermSize 最小值

例如:-XX:MaxPermSize=10M -XX:PermSize=10M

运行时方法区无法满足内存分配,也会抛出 OutOfMemoryError

3 直接内存

特点

  • 不属于运行时数据区
  • 不受 Java 堆大小的限制

JDK 1.4 的 NIO 可以直接使用 Native 函数直接分配这块内存,使用 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用

配置虚拟机参数需要考虑到这块内存,大小的分配

  • -XX:MaxDirectMemorySize 最大值,默认和 Java 堆最大值一样

例如:-XX:MaxDirectMemorySize=10M

内存申请不到后也会抛出 OutOfMemoryError

相关文章

  • [JVM] JVM内存结构浅析

    JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM高效稳定运行。 经典的JVM内存布...

  • JVM内存结构浅析

    1 概述 具有内存动态分配和自动回收的特点 2 运行时内存 2.1 程序计数器(Program Counter R...

  • JVM内存结构和Java内存模型

    最近看到两个比较容易混淆的概念:JVM内存结构和Java内存模型 JVM内存结构JVM内存结构或者说内存模型指的是...

  • JVM 内存结构解析

    1. JVM内存结构 (1) JDK1.7的JVM内存结构 JVM内存结构主要有三大块:堆内存、方法区和栈。 堆内...

  • JVM学习笔记

    一、JVM的结构图 1.1 Java内存结构 JVM内存结构主要有三大块:堆内存、方法区和栈。堆内存是JVM中最大...

  • JVM-02

    JVM内存结构

  • JVM内存模型和JVM内存结构的区别

    JVM内存模型与内存结构不是同一个概念,JVM内存结构是从运行时数据区的结构角度描述的概念,而JVM内存模型是从主...

  • 《深入理解java虚拟机》之JVM内存结构总结

    JVM内存结构 JVM内存结构不光是只有堆内存和栈内存,实际情况要复杂很多,主要包含以下结构。 程序计数器 每个线...

  • JVM

    简介 Jvm 系列一:Java类的加载机制Jvm系列二:JVM内存结构 --内存泄漏与内存溢出Jvm系列三:GC算...

  • java线程安全相关问题

    可见性问题的原因: 1.JVM内存结构: JVM的内存结构分为主内存(heap)和工作区内存。 主内存可以存放多线...

网友评论

    本文标题:JVM内存结构浅析

    本文链接:https://www.haomeiwen.com/subject/akounttx.html