JMM内存模型
● 说说JVM的主要组成部分以及作用?
类加载器、运行时数据区、执行引擎、本地库接口

类加载器子系统
它主要功能是处理类的动态加载,还有链接,并且在第一次引用类时进行初始化。
Loading - 加载,顾名思义,用于加载类,它有三种类加载器,根据双亲委托模型,从不同路径进行加载:
● Bootstrap ClassLoader - 加载 rt.jar 核心类库,是优先级最高的加载器
● Extension ClassLoader - 负责加载 jre\lib\ext 文件夹中的类
● Application ClassLoader -负责加载 CLASSPATH 指定的类库
Linking - 链接,动态链接到运行时所需的资源,分为三步:
● Verify - 验证:验证生成的字节码是否正确
● Prepare - 准备:为所有静态变量,分配内存并赋予默认值
● Resolve - 解析:将 class 文件常量池中所有对内存的符号引用,替换成到方法区的直接引用
Initialization - 类初始化,类加载的最后阶段,这里对静态变量进行赋值,并执行静态块。(注意区分对象初始化)
运行时数据区
它约定了在运行时程序代码的数据比如变量、参数等等的存储位置,主要包含以下几部分:
● PC 寄存器(程序计数器):保存正在执行的字节码指令的地址
● 栈:在方法调用时,创建一个叫栈帧的数据结构,用于存储局部变量和部分过程的结果,栈帧由以下几部分组成:
○ 局部变量表:存储方法调用时传递的参数,从0开始存储this、方法参数、局部变量
○ 操作数栈:执行中间操作,存储从局部变量表或对象实例字段复制的常量或变量值,以及操作结果,另外,还用来准备被调用方法的参数和接受方法调用的返回结果
○ 动态链接:一个指向运行时常量池的引用,将 class 文件中的符号引用(描述一个方法调用了其他方法或访问成员变量)转为直接引用
○ 方法返回地址:方法正常退出或抛出异常退出,返回方法被调用的位置
● 堆:存储类实例对象和数组对象,垃圾回收的主要区域
● 方法区:也被称为元空间,还有个别名 non-heap(非堆),使用本地内存存储 class meta-data 元数据(运行时常量池,字段和方法的数据,构造函数和方法的字节码等),在 JDK 8 中,把 interned String 和类静态变量移动到了 Java 堆
● 运行时常量池:存储类或接口中的数值字面量,字符串字面量以及所有方法或字段的引用,基本上涉及到方法或字段,JVM 就会在运行时常量池中搜索其具体的内存地址
● 本地方法栈:与 JVM 栈类似,只不过服务于 Native 方法
执行引擎
运行时数据区存储着要执行的字节码,执行引擎将会读取并逐个执行。
Interpreter - 解释器,它对字节码的解释很快,但执行慢,有个缺点是,当方法被多次调用时,每次都需要重新解释。
JIT Compiler- JIT编译器, 解决了解释器的缺点,仍使用解释器来转换字节代码,但发现有代码重复执行时,会使用 JIT 编译器,将整个字节码编译成本地代码,将本地代码用于重复调用,从而提高系统的性能,有以下几部分组成:
● 中间代码生成器 - 生成中间代码
● 代码优化器 - 负责优化上面生成的中间代码
● 目标代码生成器 - 负责生成机器代码或本地代码
● Profiler - 一个特殊组件,负责查找热点,判断该方法是否被多次调用
Garbage Collector- 垃圾收集器,收集和删除未引用的对象。
另外,还包括执行引擎所需的本地库(Native Method Libraries)和与其交互的 JNI 接口(Java Native Interface)。
● jvm内存模型,内存屏障

内存模型描述了多线程如何正确的通过内存进行交互和使用共享数据。换句话说,内存模型约束了处理器对内存的读写。内存模型就是在硬件层面描述了使用内存屏障(刷新缓存或禁用指令重排序)解决多线程编程中的可见性和有序性的问题。
Happens-Before, JMM 规定,要想保证 B 操作能够看到 A 操作的结果(无论它们是否在同一个线程),那么 A 和 B 之间必须满足 Happens-Before 关系:
● 单线程规则:一个线程中的每个动作都 happens-before 该线程中后续的每个动作
● 监视器锁定规则:监听器的解锁动作 happens-before 后续对这个监听器的锁定动作
● volatile 变量规则:对 volatile 字段的写入动作 happens-before 后续对这个字段的每个读取动作
● 线程 start 规则:线程 start() 方法的执行 happens-before 一个启动线程内的任意动作
● 线程 join 规则:一个线程内的所有动作 happens-before 任意其他线程在该线程 join() 成功返回之前
● 传递性:如果 A happens-before B, 且 B happens-before C, 那么 A happens-before C
● 对象一定分配在堆,栈对象不一定分配在堆上,JIT可以实现栈上分配
Java对象内存分配策略:

JVM在Server模式下的逃逸分析可以分析出某个对象是否永远只在某个方法、线程的范围内,并没有“逃逸”出这个范围,逃逸分析的一个结果就是对于某些未逃逸对象可以直接在栈上分配,由于该对象一定是局部的,所以栈上分配不会有问题。
JVM在内存新生代Eden Space中开辟了一小块区域,由线程私有,称作TLAB(Thread-local allocation buffer),默认设定为占用Eden Space的1%。在Java程序中很多对象都是小对象且用过即丢,它们不存在线程共享也适合被快速GC,所以对于小对象通常JVM会优先分配在TLAB上,并且TLAB上的分配由于是线程私有所以没有锁开销。
● java线程模型和jvm线程模型区分
● Java堆的内存结构?在什么地方会发生OOM?如何分析OOM发生的原因?让你自己实现OOM,你会怎么做?


JMM内存模型的更多相关文章
- JMM内存模型详解(一)
		
本文开始死磕JMM(Java内存模型)由于知识点较多,分来写 该文为JMM第一篇 技术往往是枯燥的,本文文字较多 1. JMM是什么? 其实JMM很好理解,我简单的解释一下,在Java多线程中我们经常 ...
 - JVM学习(七)JMM内存模型
		
一.什么是JMM 概念:Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能 ...
 - JMM内存模型相关笔记整理
		
JMM 内存模型是围绕并发编程中原子性.可见性.有序性三个特征来建立的 原子性:就是说一个操作不能被打断,要么执行完要么不执行,类似事务操作,Java 基本类型数据的访问大都是原子操作,long 和 ...
 - (四) 一文搞懂 JMM - 内存模型
		
4.JMM - 内存模型 1.JMM内存模型 JMM与happen-before 1.可见性问题产生原因 下图为x86架构下CPU缓存的布局,即在一个CPU 4核下,L1.L2.L3三级缓存与主内存的 ...
 - JMM内存模型+volatile+synchronized+lock
		
硬件内存模型: Java内存模型: 每个线程都有一个工作内存,线程只可以修改自己工作内存中的数据,然后再同步回主内存,主内存由多个内存共享. 下面 8 个操作都是原子的,不可再分的: 1) lock ...
 - 多线程与Java的JMM内存模型
		
共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入时,能对另一个线程可见.从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存( ...
 - JAVA并发编程的艺术 JMM内存模型
		
锁的升级和对比 java1.6为了减少获得锁和释放锁带来的性能消耗,引入了"偏向锁"和"轻量级锁". 偏向锁 偏向锁为了解决大部分情况下只有一个线程持有锁的情况 ...
 - 基础篇:深入JMM内存模型解析volatile、synchronized的内存语义
		
目录 1 java内存模型,JMM(JAVA Memory Model) 2 CPU高速缓存.MESI协议 3 指令重排序和内存屏障指令 4 happen-before原则 5 synchronize ...
 - JMM 内存模型 与 volatile 关键字
		
内存模型 线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory). 本地内存中存储了该线程以读/写共享变量的副本. 不同线程之间无法相互 ...
 - JMM内存模型、CPU缓存一致性原则(MESI)、指令重排、as-if-serial、happen-before原则
		
JMM三大特性原子性 汇编指令 --原子比较和交换在底层的支持 cmp-chxg 总线加锁机制 Synchronized Lock锁机制 public class VolatileAtomicSamp ...
 
随机推荐
- vue后台管理系统——权限管理模块
			
电商后台管理系统的功能--权限管理模块 1. 权限管理业务分析 通过权限管理模块控制不同的用户可以进行哪些操作,具体可以通过角色的方式进行控制,即每个用户分配一个特定的角色,角色包括不同的功能权限. ...
 - e.target和this区别
			
首先,this是指向当前事件所绑定的元素 e.target指向事件执行时所点击区域的元素, 易混淆点,当鼠标所点击的元素有子元素,e.target指向子元素,若没有,则和this一样指向事件所绑定的事 ...
 - 20200923--计算鞍点(奥赛一本通P91 4)
			
给定一个5*5的矩阵,每行只有一个最大值,每列只有一个最小值,寻找这个矩阵的鞍点.鞍点指的是矩阵中的一个元素,它是所在行的最大值,并且是所在列的最小值. 例如:在下面的例子中(第4行第1列的元素就是鞍 ...
 - 一种典型的不知循环次数的c语言循环问题
			
问题如图 代码如下 1 #define _CRT_SECURE_NO_WARNINGS 1 2 #include<stdio.h> 3 int main() 4 { 5 puts(&quo ...
 - 基于redis设计的秒杀活动
			
FlashSale 意为 秒杀,是电子网上商城促销活动的一种形式 本项目依赖redis,使用redis的缓存以及原子操作实现秒杀活动 依赖的包 StackExchange.Redis 该包的作用类似 ...
 - centos7 为文件夹添加写入权限
			
[root@VM-16-15-centos ~]# sudo su[root@VM-16-15-centos ~]# cd /www/wwwroot/www.htqq.sale/php/images[ ...
 - NOIP2008普及组
			
T2]排座椅 横行相同时列数+1,纵行相同时行数+1. 主要是用桶排序,因为范围太大了,用sort会超时 #include<iostream> #include<cstring> ...
 - SQL的分类
			
DDL: 数据定义语言,用来定义数据库对象(数据表,表 ,字段) : DML:数据操作语言,用来对数据库表中的数据进行增删改 : DQL:数据库查询语言,用来查询数据库中的表的记录 DCL:数据控制语 ...
 - R 曲线拐点
			
x = seq(1,15) y = c(4,5,6,5,5,6,7,8,7,7,6,6,7,8,9) plot(x,y,type="l",ylim=c(3,10)) lo < ...
 - 更新Vue-cli4与Eslint插件自动保存
			
Vue-cli更新 此更新为Vue-cli3更新为4,可使用node来查看本机的安装版本,vue -V,此版本(cli4)需要node v8.9 或更高版本 (推荐 v10 以上),查看node版本可 ...