JVM学习笔记—JVM整体架构
1.JVM整体架构
- 根据 JVM 规范,JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。
架构简介
- 线程计数器(PC计数器):
- 占用内存小,线程私有(线程隔离),生命周期与线程相同
- 大致为字节码行号指示器
- 虚拟机栈:
- 线程私有,生命周期与线程相同,使用连续的内存空间
- Java 方法执行的内存模型,存储局部变量表、操作栈、动态链接、方法出口等信息内存空间
- 堆:
- 属于内存中比较大的一块专区
- 线程共享,生命周期与虚拟机相同,可以不使用连续的内存地址
- 保存对象实例,所有对象实例(包括数组)都要在堆上分配
- 方法区:
- 线程共享,生命周期与虚拟机相同,可以不使用连续的内存地址
- 存储已被虚拟机栈加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
- 运行时常量池也在方法区中
- 本地方法栈:
- 线程私有
- 为虚拟机使用到的Native方法提供服务
2.JVM的五大模块
类装载器子系统
、运行时数据区
、执行引擎
、本地方法接口
、垃圾收集模块
。
- class文件(字节码文件)通过类加载器加载后就可以进入JVM进行解读了
- class文件想要被加载到内存中需要加载(包含三个类加载),连接(三步),初始化这三个过程
- 三个过程先执行加载,当字节码文件加载完之后,执行链接操作,链接中有三个步骤(校验,准备,解析)
- 执行完加载和连接之后会进行初始化,初始化的时候会给一些原始的字段/初始的常量一些值
- 加载完之后
字节码文件
会进入运行时数据区
- 在
运行时数据区
中有一个PC寄存器,它里面会有一些指定的编码,编码记录每一个线程执行的每一个位置,再有多个线程的时候会有多个PC寄存器 - 还有虚拟机栈去,简称栈区,栈去中会有很多个线程,还会有一些对应的小操作和对应的栈针,栈针决定着每步的猜测
- 之后加载堆区和方法区,看本地方法栈,本地方法栈主要是给本地接口提供一些服务
- 执行引擎:
- 主要的作用:将字节码转换成可以运行的二进制文件
3.JVM运行时内存
- JVM运行时内存
- Java 虚拟机有自动内存管理机制,如果出现面的问题,排查错误就必须要了解虚拟机是怎样使用内存的。
4.不同版本的JDK运行时数据区(java内存区域)的样子
- Java7和Java8内存结构的不同主要体现在方法区的实现
- 方法区是java虚拟机规范中定义的一种概念上的区域,不同的厂商可以对虚拟机进行不同的实现。
- 元空间代替原来的方法区
- 将元空间和直接内存放在本地内存中,但是本地内存不放在运行时数据区
5. JDK8虚拟机内存详解
- 本地方法栈:调用本地的一些方法
- 程序计数器:告诉我们每一个线程执行在了哪个位置
- 虚拟机栈:里面有对应的栈帧,每一个方法压栈之后都会形成一个栈帧,栈帧里面包含(局部变量表,操作栈,动态连接,方法返回地址)
- 堆:是一块比较大的区域,包含新生代(Eden,S0,S1)和老年代
- 元数据区/元空间:包含对应的常量池,方法原信息,类元信息
- JIT编译区:即时编译生产的一些缓存
6. JDK7、8变化小总结
- 线程共享的区域生命周期跟虚拟机一样
- 线程私有的区域生命周期就是单个的线程周期
- 直接内存指的就是电脑的直接内存
- JDK1.8将方法区移除,取而代之的是元空间
所以说
:- 线程私有的:
① 程序计数器
② 虚拟机栈
③ 本地方法栈 - 线程共享的:
① 堆
② 方法区
③ 直接内存(非运行时数据区的一部分)
- 线程私有的: