首页 > 系统相关 >jvm 内存结构

jvm 内存结构

时间:2023-04-14 11:58:37浏览次数:49  
标签:常量 虚拟机 线程 内存 jvm 方法 栈帧 结构

jvm 内存结构和 java 内存模型不是同一个东西

线程私有 线程共享
程序计数器
虚拟机栈 方法区
本地方法区 堆外内存(Java7的永久代或JDK8的元空间、代码缓存)

程序计数器

  • 也叫 PC 寄存器,存储下一条程序行号(严格是机器码行号),比如分支、循环、线程切换之后的唤醒等
  • 每个线程都有且互不影响,所需内存空间较小,唯一不会出现 OutOfMemoryError 的区域
  • 生命周期跟随线程的创建和结束(线程结束,这个线程的程序计数器也被销毁)

虚拟机栈

  • 存储栈帧,一个栈帧就对应一个方法的调用。类加载字节码文件时就确定好了栈帧的个数,每个类的方法在对应的字节码文件的方法表里
  • 栈帧包含局部变量表、操作数栈、动态链接、方法返回地址
    • 局部变量表:基本类型和引用对象
    • 操作数栈:方法执行过程中的计算结果
    • 动态链接:当栈帧中还需要调用别的方法时确定是哪个对象的方法
    • 方法返回地址:当前方法调用结束的结果(正常 return 或出现异常)
  • 可能出现的异常
    • StackOverFlowError:栈帧过深,调用链路太长了,比如死循环方法调用,递归没指定出口等
    • OutOfMemoryError:栈帧没有过深,但是每个栈帧要使用的内存太大导致内存不够用

本地方法栈

和虚拟机栈类似,只不过虚拟机存储调用普通方法的栈帧,本地方法栈存储的是 native 方法的栈帧

  • 此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数据都在这里分配内存
  • 为了进行高效的垃圾回收,虚拟机把堆内存逻辑上划分成三块区域(分代的唯一理由就是优化 GC 性能)
    • 新生带(年轻代):新对象和没达到一定年龄的对象都在新生代
    • 老年代(养老区):被长时间使用的对象,老年代的内存空间应该要比年轻代更大
    • 元空间(JDK1.8 之前叫永久代):像一些方法中的操作临时对象等,JDK1.8 之前是占用 JVM 内存,JDK1.8 之后直接使用物理内存

方法区

  • 与 Java 堆一样,是所有线程共享的内存区域,虽然 Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫 Non-Heap(非堆)
  • 此区域存放类信息、字段信息、方法信息、常量池、静态变量、即时编译器编译后的代码缓存等数据

元空间和永久代

  • 是方法区的具体落地实现,可以理解为方法区是接口,元空间是jdk1.8的实现,永久代是1.7的实现
  • 永久代物理是堆的一部分,受垃圾回收影响;而元空间存在于本地内存不受垃圾回收影响
  • Java7 中我们通过-XX:PermSize 和 -xx:MaxPermSize 来设置永久代参数;java8 通过-XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 用来设置元空间参数

常量池和运行时常量池

  • 常量池是 class 文件中的内容,包含类和方法的描述、成员变量、文本字符串、final 常量等
  • 运行时常量池是方法区的一部分,是在类加载的时候把 class 文件中的常量池放到 jvm 内存中(每个 class 文件会生成一个 Class 对象)

标签:常量,虚拟机,线程,内存,jvm,方法,栈帧,结构
From: https://www.cnblogs.com/hangychn/p/17317859.html

相关文章

  • Java_JVM的内存溢出异常
     JVM的内存溢出异常在Java虚拟机规范的描述中,除了PC(程序计数器)寄存器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError异常的可能。当发生OutOfMemoryError异常时,无法用try...catch捕捉。 在开始讲解之前,在这里先简单介绍下虚拟机启动相关的一些内存设置参数。因为Ou......
  • 使用反射按照类结构生成MySQL表
    因为一个表对应一个java类,如果java类多了,一个一个创建表太消耗时间了,同时也想造下轮子。加深下对反射和注解的使用反射和注解把java一切皆对象的思想完全的体现了出来,同时也给java提供了强大的动态性。主要进行工作的类,可以在里面加上jdbc,就可以实现自动创建表了。importjava.......
  • jvm 类加载
    将字节码文件加载到jvm,并创建对应的字节码对象,然后对其进行验证、初始化等操作共5个阶段:加载、验证、准备、解析、初始化,这里只记录【加载】里的类加载器和双亲委派加载的是字节码文件通过类加载器ClassLoader把字节码文件在堆中生成代表这个class文件的java.lang.Clas......
  • jvm 字节码
    编译前端编译:依靠jdk的编译工具把java文件编译成class文件,javac命令后端编译:class文件编译成机器指令逐行读取class文件内同,并解释成机器指令引入jit技术提高解释效率,比如某些类中共有的内容,这些内容解释次数过多就直接缓存起来反编译:把class文件反编译为......
  • jvm 初识
    总结jvm是一套规范,只要实现了相关规定就可以视为是一个jvm,jdk的是hotSpot,不同jdk版本的jvm也有细微差异jvm不仅可以作为java的运行环境,还能作为别的语言的运行环境,比如kotlin、groovy等java能跨平台是因为不同平台都有对应的jvm,jvm能把同样的java文件生成......
  • jvm
    1.什么情况下会发生栈内存溢出。  2.详解JVM内存模型思路:给面试官画一下JVM内存模型图,并描述每个模块的定义,作用,以及可能会存在的问题,如栈溢出等。我的答案:JVM内存结构   3.JVM内存为什么要分成新生代,老年代,持久代。新生代中为什么要分为Eden和Survivor。4.JVM......
  • 数据结构与对象------Redis
    参考《Redis设计与实现》系列文章目录和关于我一丶简单动态字符串当redis需要的不仅仅是一个字符串字面量,而是一个可以被修改的字符串值时,就会使用SDS(simpledynamicstring)来表示字符串值。比如setmsg"helloworld"将创建一个新键值对,键值对的键是一个字符串对象(存储着msg),......
  • 如何查看Linux的内存使用状况
    导读我想要监测Linux系统的内存使用状况。有哪些可用的图形界面或者命令行工具来检查当前内存使用情况?当涉及到Linux系统性能优化的时候,物理内存是一个最重要的因素。自然的,Linux提供了丰富的选择来监测珍贵的内存资源的使用情况。不同的工具,在监测粒度(例如:全系统范围,每个......
  • Linux操作系统内存管理RAID磁盘阵列与配置
    1、RAID磁盘阵列简称:独立冗余磁盘阵列把多块独立的物理硬盘按不同的方式组合起来形成一个硬盘组(逻辑硬盘)。从而提供比单个硬盘更高的存储性能和提供数据备份技术。1.1RAID级别组成磁盘阵列的不同方式称为RAID级别(RAIDLevels)常用的RAID级别:RAID0、RAID1、RAID5、RAID6、RAID1......
  • Linux操作系统ARM体系结构处理器机制原理与实现
    ARM的概念ARM(AdvancedRISCMachine),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。ARM公司并不生产芯片也不销售芯片,它只出售芯片技术授权。其合作公司针对不同需求搭配各类硬件部件,比如UART、SDI、I2C等,从而设计出不同的SoC......