• Java内存区域


    Java内存区域

    Java内存区域就是Java运行时数据区

    • 线程私有的:程序计数器、虚拟机栈、本地方法栈
    • 线程共享的:堆、方法区

    1.程序计数器

    程序计数器是什么:可以看作是当前线程所执行的字节码的行号指示器

    程序计数器的作用:

    • 实现代码的流程控制
    • 确保线程切回时抵达正确位置

    2.虚拟机栈

    栈是 JVM 运行时数据区域的一个核心,除了一些 Native 方法是本地方法栈实现的

    其他所有 Java 方法的调用都是由虚拟机栈协助执行的

    虚拟机栈由一个个栈帧组成,栈帧的组成有:

    • 局部变量表
    • 操作数栈
    • 动态链接
    • 方法返回地址

    接下来我们一个个说明他们的作用

    局部变量表

    局部变量表用来存放:

    • 方法的this对象
    • 方法的参数
    • 方法内部定义的局部变量

    局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序被编译成Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的最大局部变量表的容量。

    操作数栈

    操作数栈也是栈结构,可以简单的理解它的作用就是方法中变量进行运算

    动态链接

    主要服务一个方法调用另一个方法的场景

    动态链接的作用就是为了将符号引用转换为直接引用

    方法返回

    无论方法采用何种方式退出,在方法退出后都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在当前栈帧中保存一些信息,用来帮他恢复它的上层方法执行状态。
    方法退出过程实际上就等同于把当前栈帧出栈,因此退出可以执行的操作有:恢复上层方法的局部变量表和操作数栈,把返回值(如果有的话)压入调用者的操作数栈中,调整PC计数器的值以指向方法调用指令后的下一条指令。
    一般来说,方法正常退出时,调用者的PC计数值可以作为返回地址,栈帧中可能保存此计数值。而方法异常退出时,返回地址是通过异常处理器表确定的,栈帧中一般不会保存此部分信息。

    3.本地方法栈

    调用Native方法

    4.堆

    堆是线程共享的。

    JDK7版本以及JDK7版本之前,堆内存通常分为下面三部分:

    1. 新生代(年轻代)内存
    2. 老年代
    3. 永久代

    下图中的Eden区、两个S区S0、S1都属于新生代

    在这里插入图片描述

    在这里插入图片描述

    JDK8版本之后永久代被元空间取代,元空间使用的是直接内存

    在这里插入图片描述

    元空间,不再与堆连续,而是直接存在于本地内存,也就是机器的内存。理论上机器内存有多大,元空间就有多大。

    在之前的版本中,字符串常量池存在于永久代中,在大量使用字符串的情况下,容易出现OOM异常,此外JVM加载的class总数、方法的大小等都很难确定,因此对永久代大小难以确定。

    5.方法区

    当虚拟机要使用一个类时,它需要读取并解析 Class 文件获取相关信息,再将信息存入到方法区。方法区会存储已被虚拟机加载的 类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据

    主要是存放一个类的:

    基础信息

    常量池

    字段

    方法

    法区会存储已被虚拟机加载的 类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据

    主要是存放一个类的:

    基础信息

    常量池

    字段

    方法

    属性

  • 相关阅读:
    机器视觉检测--相机
    mysql主主复制
    编写一个Book类,需要进行封装,对外提供set和get方法且对页数进行控制
    JS中原型相关的十个知识点总结
    简易版Pycharm(2023)+Conda开发环境配置教程
    零号培训平台课程-1、SQL注入基础
    图像处理ASIC设计方法 笔记2 图像边界镜像处理
    串口通信
    SIP会话发起协议 - 先知道是什么(一)
    java毕业设计在线售药系统Mybatis+系统+数据库+调试部署
  • 原文地址:https://blog.csdn.net/m0_64201189/article/details/136435783