• Java 虚拟机二三事:Java内存区域


    在这里插入图片描述
    Java 内存区域是指 JVM 运行时将数据分区域存储 ,简单的说就是不同的数据放在不同的地方。通常又叫 运行时数据区域,分为堆、栈、方法区、程序计数器。其中栈又分为虚拟机栈和本地方法栈。
    线程共享的区域为方法区和堆,线程私有的区域为程序计数器、方法区。

    Java 内存模型(JMM)定义了程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。

    程序计数器

    线程私有。
    通过改变计数器的值来选取下一条要执行字节码指令。分支、跳转、循环、异常处理、线程恢复都需要它。
    为了保证线程切换后能恢复到正确的执行位置,每个线程都有1个独立的程序计数器,每个线程之间的计数器不相互影响,这就是线程私有内存。

    • 如果是一个Java方法,记录的是虚拟字节码指令的地址
    • 如果一个Native方法,这个计数器为空

    是唯一一个虚拟机没有规定OOM的区域

    虚拟机栈

    线程私有。
    它描述的是Java方法执行的内存模型,每个方法在执行的时候都创建一个栈帧,每个方法从执行到结束的过程就是栈帧压栈到出栈的过程。
    在这里插入图片描述

    每个栈帧都有局部变量表,局部变量表存储的是各种基本数据类型和对象引用
    虚拟机规范中规定了2种异常

    • StackOverflowException,当线程请求的深度大于虚拟机所允许的栈深度
    • OOM,虚拟机支持动态扩展,当无法申请到足够的内存,就会抛出这个异常

    本地方法栈

    线程私有。
    与虚拟机栈相同,不过执行的Native方法

    线程共享。
    Java虚拟机中管理的内存最大的一块,唯一的目的就是存放对象实例,几乎所有的对象都是在这里分配内存。
    是垃圾回收器管理的主要区域,现在收集器采用的基本上都是分代回收算法。Java堆可以分为新生代和年老代,新生代还可以分为Eden、From Survicor、To Survicor区域
    在这里插入图片描述

    方法区

    在这里插入图片描述

    线程共享。
    存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码。
    这个区域的内存回收主要是针对常量池的回收和对类型的卸载。
    运行时常量池是方法区的一部分,用于存放编译器生成的各种字面量和富豪已用,这部分内容将在类加载后进入方法区的运行时常量池中堆放。
    如果生成了大量的类填满了方法区,会导致OOM。

    其他

    JDK1.8及之后,用元空间代替了方法区。

    Java内存模型

    在这里插入图片描述

    • 线程之间的共享变量存在主内存中
    • 每个线程都有自己私有的本地内存,存储了共享变量的本地副本

    线程间的通信必须经过主内存,也就是线程A和B要通信的话,必须要经过2个步骤

    1. 线程A把本地内存中更新的共享变量刷新到主线程中去
    2. 线程B到主内存中去读取线程A之前已经更新过的共享变量

    参考

    https://segmentfault.com/a/1190000038190582
    《深入理解JAVA虚拟机》

  • 相关阅读:
    Python配置镜像源
    JDK1.8中的Stream流源码中的常用方法全面解析附代码演示及源码展示
    HTTP请求交互基础(基于GPT3.5,持续更新)
    Win11 25188.1000补丁包介绍及下载地址
    JS的装箱和拆箱
    不标年份的葡萄酒质量好吗?
    【Python第三方包】ocr文字识别(pyocr)
    gRPC 自定义负载均衡算法
    计算机网络谢希仁第七版课后答案-第二章 物理层(1-19题)
    Android GUI系统之SurfaceFlinger(16)MessageBase解读
  • 原文地址:https://blog.csdn.net/one1go/article/details/125469463