JVM原理-jvm内存模型
一、jvm内存模型
- 结构图
JVM包含两个子系统和两个组件
- Class loader(类装载子系统)
根据给定的全限定名类名(如:java.lang.Object)来装载class文件到
Runtime data area运行时数据区中的method area方法区中 - Execution engine(执行引擎)
执行classes中的指令 - Runtime data area(运行时数据区)
我们常说的JVM的内存 - Native Interface(本地接口)
与native libraries交互,是其它编程语言交互的接口 - 运行流程
首先通过编译器把 Java 代码转换成字节码,类加载器
(ClassLoader)再把字节码加载到
内存中,将其放在运行时数据区
(Runtime data area)的方法区内,而字节码文件只是 JVM 的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器执行引擎
(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口
(Native Interface)来实现整个程序的功能
1、运行时数据区
- 结构图
- 程序计数器(Program Counter Register)
当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;
- Java 虚拟机栈(Java Virtual Machine Stacks)
每个方法在执行的同时都会在Java 虚拟机栈中创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息;
- 本地方法栈(Native Method Stack)
与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;
- Java 堆(Java Heap)
Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;
- 方法区(Methed Area)
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
1.1、程序计数器(Program Counter Register)
- 程序计数器它是一个块较小的内存空间,保存了当前线程正在执行的字节码指令的地址
- 由于JVM的多线程是通过线程轮流切换来分配CPU执行时间的方式实现的,一个CPU只能处理一个线程的业务。线程切换后,程序计数器会记录当前线程执行的字节码指令的地址(行号),当线程再次分配到CPU时,通过程序计数器记录的行号找到上次字节码执行的地址继续执行。程序计数器是
线程私有
的,它是JVM中唯一没有规定OutOfMemoryError情况
的区域。
1.2 、Java 虚拟机栈(Java Virtual Machine Stacks)
- JAVA虚拟机是
线程私有
的,生命周期和线程相同 - 虚拟机栈描述的是JAVA方法执行的内存模型,每个方法执行的时候,会创建一个栈帧(Stack Frame)来储存局部变量表、操作数栈、动态链接、方法出口等信息
- 栈帧
栈帧是虚拟机的单位,一个方法一个栈帧,用来储存局部变量、操作数栈、动态链接、方法出口等信息
局部变量表
用来存储我们临时8个基本数据类型、对象引用地址、returnAddress类型(字节码的指令地址)操作数栈
操作数栈就是用来操作的,例如代码中有个 i = 6*6,他在一开始的时候就会进行操作,读取我们的代码,进行计算后再放入局部变量表中去动态链接
如方法中需要大量计算的,把计算的代码封装成一个add()方法,当前方法调用add()方法,跳转过去,add()就是动态链接方法出口
出口正常的话就是return 不正常的话就是抛出异常落
1.3、JAVA堆(Java Heap)
- JAVA堆是虚拟机内存最大的一块区域,所有线程共享,虚拟机启动时就创建,用来储存对象实列
- 所有的对象实例和数组都在堆上分配
- 垃圾收集器管理的主要区域,被称为“GC堆”
- 从内存回收的角度来看,JAVA堆可分为
新生代和老年代
- 从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区
- 如果堆中没有内存可以完成实例分配,并且堆也无法再扩展时,将会抛OutOfMemoryError异常
1.4、方法区(Methed Area)
- 方法区是所有线程共享,用于储存已被JVM加载的
类信息、常量、静态变量
等信息,就是javac编译器编译后的代码数据 - 当方法区无法满足内存分配需求时,抛出OutOfMemoryError异常
1.5 、堆栈的区别
对比 | JVM堆 | JVM栈 |
---|---|---|
物理地址 | 堆的物理地址分配对对象是不连续的。因此性能慢些。在GC的时候也要考虑到不连续的分配,所以有各种算法。比如,标记-消除,复制,标记-压缩,分代(即新生代使用复制算法,老年代使用标记——压缩) | 栈使用的是数据结构中的栈,先进后出的原则,物理地址分配是连续的。所以性能快 |
内存分配 | 堆的内存空间是不连续的,所以分配的内存是在运行期确认的,因此大小不固定。一般堆大小远远大于栈 | 栈的内存空间是连续的,所以分配的内存大小要在编译期就确认,大小是固定的 |
存放内容 | 堆存放的是对象的实例和数组。更关注的是数据的存储 | 局部变量、操作数栈、动态链接、返回结果 ,更关注的是程序方法的执行 |
程序可见性 | 堆是所有线程共享的,对于整个应用程序都是共享、可见的 | 栈是线程私有的,仅对当前线程可见,生命周期和线程相同 |
2、Execution engine(执行引擎)
虚拟机核心的组件就是执行引擎,它负责执行虚拟机的字节码,字节码文件只是 JVM 的一套 指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的要JVM字节码执行引擎
(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行
3、类加载器(Class loader)
- 定义
根据指定全限定名称将class文件加载到JVM内存,转为Class对象
3.1、 四种类加载器
启动类加载器
(Bootstrap ClassLoader):用来加载java核心类库,无法被java程序直接引用扩展类加载器
(extensions class loader):用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类系统类加载器
(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取它用户自定义类加载器
:通过继承 java.lang.ClassLoader类的方式实现
3.2、类装载的执行过程
- 加载:根据查找路径找到相应的 class 文件然后导入
- 验证:检查加载的 class 文件的正确性
- 准备:给类中的静态变量分配内存空间
- 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,在直接引用直接指向内存中的地址
- 初始化:对静态变量和静态代码块执行初始化工作
3.3、双亲委派模型
- 双亲委派模型工作流程
一个类加载器收到类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器完成。每个类加载器都是如此,只有当父加载器在自己的搜索范围内找不到指定的类时(即ClassNotFoundException),子加载器才会尝试自己去加载。
- 作用
如果没有双亲委派,那么用户是不是可以自己定义一个java.lang.Object的同名类,java.lang.String的同名类,并把它放到ClassPath中,那么类之间的比较结果及类的唯一性将无法保证,因此,为什么需要双亲委派模型?防止内存中出现多份同样的字节码
- 打破双亲委派机制
-打破双亲委派机制则不仅要继承ClassLoader类,还要重写loadClass和findClass方法
4、直接内存
- 直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致 OutOfMemoryError 异常出现
- 可以理解为基于物理内存和Java虚拟机内存的中间内存
二、垃圾回收机制及算法
------JVM原理-垃圾回收机制及算法
JVM原理-jvm内存模型相关推荐
- Java工程师必备:JVM原理、内存模型、调优、垃圾回收机制、面试题
在如今这个时间和知识都是碎片化的时代,C站根据C1-C4认证的成长路径,进行知识细化整理,形成系统化的知识图谱. 通过调研一线互联网大厂的招聘JD,小编对标C站能力认证要求,为大家整理了系列技术干货合 ...
- JVM学习--(二)内存模型、可见性、指令重排序
我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再 ...
- Java虚拟机(JVM)与Java内存模型(JMM)学习笔记
Java虚拟机[JVM]与Java内存模型[JMM]学习笔记 Java虚拟机(JVM) 三种JVM JVM 位置 JVM的主要组成部分及其作用 类加载器 双亲委派机制 沙箱安全机制 Java本地接口( ...
- JVM学习 - 体系结构 内存模型
2019独角兽企业重金招聘Python工程师标准>>> 一:Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代" ."非堆&quo ...
- jvm(12)-java内存模型与线程
[0]README 0.1)本文部分文字描述转自"深入理解jvm",旨在学习"java内存模型与线程" 的基础知识: [1]概述 1)并发处理的广泛应用是使得 ...
- java runtime类 heap_Java 进阶(一) JVM运行时内存模型
1.JVM运行时数据区域的划分 a.程序计数器(Program Counter Register) 一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.每个线程拥有独立的一个计数器,如果 ...
- Java Jvm虚拟机的内存模型概述 《对Java的分析总结》(一)
<对Java的分析总结>-Java虚拟机的内存模型 ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 头条同步 百度同步 本文章首发于微信公众 ...
- JVM学习-Java内存模型JMM
目录 1.Java内存模型概述 2.原子性 2.1.问题提出 2.2.问题分析 2.3.解决办法 3.原子性 3.1.退不出的循环 3.2 解决方法 3.3 可见性 4.有序性 4.1.诡异的结果 4 ...
- java虚拟机jvm与Java内存模型(JMM)
Java内存模型(JMM) Java 内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存.Java 内存模型(JMM) 抽象了线程和主内存之间的关系,就比如说线程之间的共享变量必须存 ...
- JVM之Java内存模型(基于《深入理解Java虚拟机》之第12章Java内存模型与线程)(上)
多任务处理为什么在OS中几乎是一项必备的功能? sadsa sadsa①.计算机的运算能力强大了,但其运算速度与它的存储和 通信子系统的速度 差距太大了,不匹配,大量的时间都花费在磁盘I/O.网络通信 ...
最新文章
- 使用QT定时器 隐藏 label
- 单网卡Squid AS4 U5 设置
- C/C++ 宏定义中#、##、#@的区别
- 内核和用户模式下进程与线程创建
- docker 容器commit指令和export指令有什么区别?(commit保存镜像提交历史记录,export不保存)
- Java SimpleTimeZone equals()方法与示例
- php商品评价代码,php商品对比功能代码分享
- 在python中查看关键字、需要执行,如何在一个文本文件,二进制执行搜索来搜索一个Python关键字?...
- 更改一个主键的列的类型的步骤
- spring mysql防注入攻击_【spring】(填坑)sql注入攻击 - 持久层参数化
- mysql i o开启_MySQL從屬I/O線程不運行。
- 手把手教你搞懂麦克风的技术指标
- win10家庭版调出组策略_普通用户选择哪个Win10系统版本?家庭版与专业版的对比介绍...
- Unity3D游戏开发引擎的产品特点
- 微医在港招股书失效:曾多次喊话上市,注册用户达2.2亿
- (转)归江:投资,心平气和结硕果
- 计算机控制实验PID数字控制器设计,实验二数字PID控制器的设计
- Vasicek短期利率模型
- 这个专业的应届生火了!年薪50万,没出校门就被挖走
- 北京大学OJ-1006源码
热门文章
- 磁力云播Android代码,磁力云播
- dwf怎么合成一个_PC-3000 Data Extractor如何将一系列Bin文件合并为一个镜像文件
- 以计算机基础知识做二十张ppt,计算机基础知识教程.ppt
- 微星小飞机界面翻译_小巧高效翻译软件Xtranslator的正确使用姿势
- 一、NPP/VIIRS夜间灯光数据校正一理论介绍
- getchar与getch函数的区别
- String[]与ListString 相互转换 KKK笔记
- java私塾初级_Java私塾初级教程-19
- STC12参考例程(附模块资料代码注释、学习经验总结)
- Vbs调用MsAgent组件,很有趣