jvm 内存模型介绍
一、类加载子系统
1、类加载的过程:装载、链接、初始化,其中,链接又分为验证、准备和解析
装载:加载class文件
验证:确保字节流中包含信息符合当前虚拟机要求
准备:分配内存,设置初始值
解析:将变量从符号引用改为直接引用
初始化:执行类构造器方法
2、类加载器的分类
加载阶段使用到类加载器,类加载器分为:由C++实现的引导类加载器和由java实现的自定义加载器
自定义加载器又分为三层类加载器:拓展类加载器,应用程序类加载器和系统类加载器
①、引导类加载器:启动类加载器,将lib目录下,或-Xbootclasspasth参数指定路径存放的,java虚拟机能识别的类库加载进虚拟机;
②、拓展类加载器:将\lib\ext目录中,或者被java.ext.dirs系统变量所指定的路径中所有的类库加载进虚拟机;
③、系统类加载器:应用程序类加载器:负责加载用户类路径上所有的类库,可以直接在开发中使用这个类加载器;
④、自定义类加载器:用户自定义的类。
3、双亲委派机制
java虚拟机对class文件采用按需加载的方式,即在需要使用到类时,才加载对应的类到内存中,并且使用双亲委派机制的模式进行加载:
①:当一个类加载器收到了类加载的请求,不会立刻自己加载,而是将请求委托给父类的加载器去加载;
②、当父类加载器还存在父类加载器,则继续往上依次委托,最终的委托到最顶层的启动类加载器;
③、如果父类的加载器可以完成类加载器,则成功返回;如果父类加载器无法完成加载,子类加载器才会尝试着自己去加载。
这就是双亲委派机制的加载过程。
双亲委派机制的优势:
可以避免类的重复加载;
保护程序的安全,避免核心的api被篡改。
4、沙箱安全机制
java代码被限定在虚拟机特定的运行范围中,并且严格限制代码对本地资源的访问,通过这样来保护代码的的有效隔离性,防止本地系统造成破坏,这就是沙箱安全机制。
沙箱主要限制系统资源访问,例如:cpu、内存,文件系统、网络。不同级别的代码相对这些资源的访问的限制也可以是不一样的。
二、运行时数据区
1、虚拟机栈
每个线程在创建的时候,都会创建一个虚拟机栈,虚拟机栈是属于线程私有的。
a、栈帧(Stack Frame)
虚拟机栈中会存放着一个一个的栈帧,一个栈帧对应着一个方法,用于支持方法的调用和方法执行的数据结构;
虚拟机栈帧中存放着方法的局部变量表、操作数栈、动态链接和方法返回地址,在编译代码时,栈帧中需要多大的局部变量表和多深的操作数栈都已经确定好了。
①局部变量表:是一组变量值存储空间,用于存放方法参数和方法内定义的局部变量。注意:在mian()方法中,第一个表中的第一个位置的参数是args;
局部变量表存放了编译器可知的各种基本数据类型,对象引用和方法返回地址;
局部变量表以变量槽为最小单位,每个槽可以存放32位的长度,即long类型和doubule类型占俩个变量槽,而其他的基本数据类型占一个变量槽。
②操作数栈:用于保存计算过程中的中间结果,同时作为计算过程中变量的临时存放空间;
③动态链接:指向运行时常量池中该帧所属方法的引用;包含这个引用的目的是为了支持当前方法的代码能够实现动态链接,如:invokedynamic指令。
在java源文件被编译到字节文件中时,所有的变量和方法引用都作为符号引用保存在class文件的常量池里,程序运行时将其加载进方法区的运行时常量池中;
如描述一个方法调用了另外的其他方法时,就是 通过常量池中指向方法的符号引用来表示的,那么动态链接的作用就是为了将这些符号引用 转为调用方法的直接引用。
④方法返回地址:存放该方法在寄存器中的值,即是该方法的指令地址,方便执行引擎在执行完该方法后,回到该方法对应的指令行号,这样才能继续执行下去。
2、程序计数器
程序计数器,又称pc寄存器,存储下一条要执行的指令的地址,每个线程都有专属的pc寄存器。
程序执行时,会不停的切换不同的线程进行执行,有些线程可能执行一般,就被停止执行,转而执行其他线程,这时候pc寄存器会记录下知道到的指令行号,等到线程获取到资源重新执行时,会依据pc寄存器中的指令,继续往下执行。
3、堆
堆由新生代和老年代组成
新生代
新生代由Eden区(伊甸园区)和俩个Survior(幸存区),Survior0,Survior1,新生代一般用来存放新创建的对象。
①Endn区:几乎所有的对象都在Eden区中创建,即Eden是大部分对象产生的地方;
创建的对象有部分存在的周期很短,有些对象的存在周期很长,当Eden区的内存满了时,会触发Minor GC 进行垃圾收集;
②Survior区: 幸存区 ,幸存区划分为俩个区Survior0和Surivor1即,幸存区0和幸存区1,在进行垃圾收集时,哪个区为空则为Survior0;一般都是俩个区互相替换成为Survior0;
Survior0 和Survior1俩个区的存储空间一般为1:8的比例,但实际大多数情况都达不到这个比例,可以使用-XX:SurviorRatio参数进行设置。
老年代
老年代一般用来存放生存周期较长的对象,当老年代的存储空间不足时,会触发Major GC或Full GC进行垃圾收集。
新生代和老年的存储空间比例为1:2,可以通过 -XX:NewRatio 参数进行设置。
垃圾收集
在堆中,有三个垃圾收集算法:Minor GC、Major GC 和 Full GC
①Minor GC
新生代垃圾收集,只是新生代(Eden、Survior0和Survior1)的垃圾收集。
触发机制:当新生代中的Eden区的空间不足时触发(注意:Survior区空间不足时不会主动触发,Survior区只会被动触发机制)进行垃圾收集。因为大多数java对象都具备朝生夕灭的特性,所以Minor GC触发的非常频繁,一般回收的速度也比较快。
收集过程:a、新生代中,对于每个对象都有一个引用计数器,当Eden区的空间满了只有,只有还被引用的对象能存活不被清理,并且会转移到Survior0区,对象的引用计数器增加1,代表这个对象存活的年龄增大一岁;
b、重复a步骤,将存活的对象复制到S0区,存活年龄增大,已存在在S0区的对象也相对应的增加存活年龄;
c、当Eden区和S0区空间满时,会将S0中的对象转移到S1中,存活的对象相对应的存活年龄,然后Eden和S0区会被清空,存活的对象全部在S1中,并且对象的存在着不一样的存活年龄。此时S0会变成意义上的S1(区中为空),S1会变成意义上的S0;如此反复,空的区为S1,对象存活的数据区为S0。
d、当不断进行Minor GC知道对象的存活年达到阈值(通过-XX:MaxTenuringThreshold设置,默认是15),则达到阈值年龄的对象,会判定为生命周期较长的对象,会被promote到老年代;不断的进行Minor GC,也会不断有对象被promote到老年代中。
TLAB:TLAB是一块为了解决线程安全问题所设置的存储空间,属于新生代的Ede区,TLAB内存空间非常小,仅占Eden的1%,不是所有的对象的实例都能在TLAB中成功分配内存,但JVM确实是以TLAB作为分配内存的首选。
堆空间是所有线程共享的,但Eden中的TLAB是线程私有的,解决线程的安全问题。
Major GC
老年代垃圾收集,只进行老年代的垃圾收集。
一个对象如果很大,那么会直接进入老年代中,即老年代存在着大对象和存活周期长的对象。
触发机制:老年代的空间不足时,会尝试触发Minor GC 进行新生代的垃圾收集,如果触发后空间还是不足,则触发Major GC;
Major GC的速度一般会比Minor GC的速度慢10倍以上,STW的时间更长,如果触发后依旧空间不住,则报OOm错误。
一把只有CMS GC 会有单独收集老年代的行为,很多时候,Major GC和 Full GC都是混淆这是用触发。
收集过程:一般Major GC 和 Full GC 同时触发,收集整个堆。
Full GC
整堆收集,收集整个java堆和方法区的垃圾。
触发机制:a、调用System.gc()时,系统会建议执行Full GC,但不必然执行;
b、老年代空间不足时;
c、方法区空间不足时;
d、通过Minor GC后进入老年代的平均大小大于老年代的可用内存;
e、有Eden区、Survior space0(From space) 区向Survior space(To space)区复制时,对象大小大于 To space的可用空间大小,则对象复制到老年代,但对象大小又大于老年代可用空间时触发。
Full GC是开发或调优中尽量避免的,这样暂停的时间会短一些
代码优化
堆不是分配对象存储的唯一选择,如果经过逃逸分析后发现,一个对象并没有逃逸出方法的话,那么可能被优化成栈上分配。
逃逸分析:分析一个对象的作用域,当一个对象在方法中定以后,对象只在方法内部使用,则认为没有发生逃逸;当一个对象定以后,它被外部方法所用(例如:return了变量或作为参数传递到了其他方法),则认为发生了逃逸。
栈上分配:没有发生逃逸的对象,可以分配到线程专属的栈上,随着方法执行的结束,栈空间也被移除,变量也被移除,无需进行GC。
代码优化(不发生逃逸分析的情况)
1、栈上分配;
2、同步省略:变量只有一个线程访问,取消其同步策略;
3、分离对象或标量替换
标量:指一个无法再分解成更小的数据的数据,如基本数据类型。
分离对象或标量替换就是将一个大的对象分解成多个标量存放在不连续的内存地址。
4、方法区 -- Metaspce 元空间
方法区和java对是一样的,是各个线程共享的区域,它用于存储已被加载类的信息,常量,静态变量,即使编译偶的代码等数据。
元空间的演进
5、本地方法栈
java虚拟机栈用于管理java方法的调用,而本地方法栈用于管理对本地方法的调用。
本地方法:java调用非java代码的接口,如操作系统或和某些硬件交换信息。
java应用对java外部的环境交互,这就是本地方法存在的原因。
当一个线程调用一个本地方法时,它就进入了一个新的并且不再受java虚拟机限制的世界,它和虚拟机拥有一个样的权限。
相关文章:
jvm 内存模型介绍
一、类加载子系统 1、类加载的过程:装载、链接、初始化,其中,链接又分为验证、准备和解析 装载:加载class文件 验证:确保字节流中包含信息符合当前虚拟机要求 准备:分配内存,设置初始值 解析&a…...
用Jmeter进行压测详解
简介: 1.概述 一款工具,功能往往是很多的,细枝末节的地方也很多,实际的测试工作中,绝大多数场景会用到的也就是一些核心功能,根本不需要我们事无巨细的去掌握工具的所有功能。所以本文将用带价最小的方式讲…...
Mysql001:(库和表)操作SQL语句
目录: 》SQL通用规则说明 SQL分类: 》DDL(数据定义:用于操作数据库、表、字段) 》DML(数据编辑:用于对表中的数据进行增删改) 》DQL(数据查询:用于对表中的数…...
甲骨文全区登录地址
日本东部 东京 https://console.ap-tokyo-1.oraclecloud.com https://console.ap-tokyo-1.oraclecloud.com 日本中部 大阪 https://console.ap-osaka-1.oraclecloud.com https://console.ap-osaka-1.oraclecloud.com 韩国中部 首尔 https://console.ap-seoul-1.oraclecloud.c…...
Java面试题第八天
一、Java面试题第八天 1.如何实现对象克隆? 浅克隆 浅克隆就是我们可以通过实现Cloneable接口,重写clone,这种方式就叫浅克隆,浅克隆 引用类型的属性,是指向同一个内存地址,但是如果引用类型的属性也进行浅克隆就是深…...
什么是同步容器和并发容器的实现?
同步容器和并发容器都是用于在多线程环境中管理数据的容器,但它们在实现和用法上有很大的区别。 同步容器: 同步容器是使用传统的同步机制(如synchronized关键字或锁)来保护容器内部数据结构的线程安全容器。同步容器通常是单线…...
学Python的漫画漫步进阶 -- 第十六步
学Python的漫画漫步进阶 -- 第十六步 十六、多线程16.1 线程相关的知识16.1.1 进程16.1.2 线程16.1.3 主线程 16.2 线程模块——threading16.3 创建子线程16.3.1 自定义函数实现线程体16.3.2 自定义线程类实现线程体 16.4 线程管理16.4.1 等待线程结束16.4.2 线程停止 16.5 动动…...
MySQL 8.0 OCP (1Z0-908) 考点精析-架构考点5:数据字典(Data Dictionary)
文章目录 MySQL 8.0 OCP (1Z0-908) 考点精析-架构考点5:数据字典(Data Dictionary)File-based Metadata Storage (基于文件的元数据存储)Transactional Data Dictionary (事务数据字典)Serialized Dictionary Informat…...
7分钟了解ChatGPT是如何运作的
ChatGPT是现在最为热门的聊天助手应用,它使用了一个大型语言模型(LLM),即GPT-3.5。它通过大量的文本数据进行训练,以理解和生成人类语言。但是,你是否有了解过ChatGPT是如何运作的吗? 下面我们就一起通过这个视频来一起…...
蓝桥杯打卡Day8
文章目录 C翻转矩阵幂 一、C翻转IO链接 本题思路:本题需要找出顺时针旋转和逆时针旋转的规律,然后就可以解决该问题。 矩阵顺时针90旋转规律:列号变为行号,(n-行号-1)变为列号 规律:a[i][j]b[j][n-i1]; 矩阵逆时针90旋转规律:行号变为列号࿰…...
React 学习笔记目录
学习使用的开发工具 编译器 VSCode 开发语言工具 TypeScript /JavaScript 重要程度分类 一般 这个程度的知识点主要是达到熟练掌握即可,不用太深入研究和学习。 重要 这个程度的知识点主要是达到熟练掌握,并且内部的原理切要熟记,因为会关…...
一起Talk Android吧(第五百五十一回:如何自定义SplashScreen)
文章目录 概念介绍实现方法修改启动页中的内容修改启动页显示时间修改启动面消失时的页面各位看官们大家好,上一回中咱们说的例子是"如何适配SplashScreen",本章回中介绍的例子是" 如何自定义SplashScreen"。闲话休提,言归正转,让我们一起Talk Android…...
PYTHON-模拟练习题目集合
🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…...
UE5学习笔记(1)——从源码开始编译安装UE5
目录 0. 前期准备1. Git bash here2. 克隆官方源码。3. 选择安装分支4. 运行Setup.bat,下载依赖文件5. 运行GenerateProjectFiles.bat生成工程文件6. 生成完成,找到UE5.sln/UE4.sln7. 大功告成 0. 前期准备 0.1 在windows的话,建议装一个Git…...
DP读书:《openEuler操作系统》(二)操作系统的发展史
操作系统的发展历史 操作系统的发展历史手工操作时代批处理系统多道程序系统分时操作系统CTSSMULTICS的历史UNIX和Linux的历史Debian系列Red Hat系列 DOS和Windows的历史DOS的历史:Windows的历史: Android和iOS的历史Android:iOS:…...
SQL sever中相关查询
目录 一、简单查询 二、条件查询 三、别名查询 四、分组查询 五、排序查询 六、去重查询 七、分页查询 八、模糊查询 九、表连接查询 十、子查询 十一、嵌套查询 一、简单查询 简单查询是最基本的查询类型,用于从数据库中选择特定列或所有列的数据。 1…...
Java手写IO流和案例拓展
Java手写IO流和案例拓展 1. 手写IO流的必要性 在Java编程中,IO流是非常重要的概念。尽管Java已经提供了许多现成的IO类和方法,但是了解IO流的底层实现原理,能够手写IO流是非常有必要的。手写IO流可以帮助我们更深入地理解IO的工作原理&…...
Linux入门教程||Linux 文件与目录管理
我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /。 其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们。 在开始本教程前我们需要先知道什么是绝对路径与相对路径。 绝对路径: 路径的写法,由根目录 /…...
MyBatis获取参数值的两种方式#{}和${} 以及 获取参数值的各种情况
一、参数值的两种方式#{}和${} 在 MyBatis 中,可以使用两种方式来获取参数值:#{} 和 ${}。 1. #{}:这是 MyBatis 推荐使用的方式。在 SQL 语句中使用 #{},MyBatis 会自动将参数值进行预编译处理,防止 SQL 注入攻击&a…...
(手撕)数据结构--->堆
文章内容 目录 一:堆的相关概念与结构 二:堆的代码实现与重要接口代码讲解 让我们一起来学习:一种特殊的数据结构吧!!!! 一:堆的相关概念与结构 在前面我们已经简单的学习过了二叉树的链式存储结…...
[运维|数据库] MySQL 中的COLLATE在 PostgreSQL如何表示
在 PostgreSQL 中,字符集(collation)和排序规则(collation order)的概念与 MySQL 类似,但语法和用法略有不同。在 PostgreSQL 中,字符集和排序规则通常是数据库、表或列级别的设置,而…...
【Linux】tar 与 zip 命令
tar 命令 tar 本质上只是一个打包命令,可以将多个文件或者文件夹打包到一个 tar 文件中,结合其他的压缩程序再将打包后的档案文件压缩。 所以看到 .tar.gz, .tar.bz2, .tar.xz 等等文件其实是 tar 文件之后进行 Gzip, Bzip2, XZ 压缩之后的文件。 tar…...
VS2015+opencv 3.4.6开发环境
VS2015+opencv 3.4.6开发环境 一、安装包下载二、安装过程三、VS环境配置四、测试一、安装包下载 这里提供两种下载方法: 1. opencv官网 2. csdn资源下载 二、安装过程 2.1 下载opencv-3.4.6 安装包 2.2 双击开始安装,选择要安装目录,点击Extract。 2.3 等待解…...
[运维|数据库] 将mysql的null.unix_timestamp(now()) * 1000转为PostgreSQL的语法
在 PostgreSQL 中,您可以使用以下方式将 MySQL 中的 UNIX_TIMESTAMP 和 NOW() 函数的组合转换为等效的语法: EXTRACT(EPOCH FROM NOW()) * 1000在这个 PostgreSQL 表达式中: EXTRACT(EPOCH FROM NOW()) 获取当前时间戳的秒数。 2. * 1000 将…...
springboot使用filter增加全局traceId,方便日志查找
一:引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> 二:编写过滤器: package com.example.demo.filter;import or…...
面经学习三
目录 Java 与 C 的区别 面向对象和面向过程的区别 面向对象特性 Java的基本数据类型 深拷贝和浅拷贝 Java创建对象的几种方式 final, finally, finalize 的区别 Java 与 C 的区别 Java 是纯粹的面向对象语言,所有的对象都继承自 java.lang.Object,…...
Open3D 点云配准——可视化匹配点对之间的连线
点云配准 一、算法原理1、概述2、主要函数二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、概述 可视化源点云和目标点云中匹配点对之间的连线,这对于点云配准,尤…...
io多路复用之poll的详细执行过程
1.结构体struct pollfd的定义 struct pollfd { int fd; /* 文件描述符 */ short events; /* 想要监视的事件(input/output/priority) */ short revents; /* 实际发生的事件(返回的事件) */ }; 2.定义po…...
网络安全深入学习第四课——热门框架漏洞(RCE— Log4j2远程代码执行)
文章目录 一、log4j2二、背景三、影响版本四、漏洞原理五、LDAP和JNDI是什么六、漏洞手工复现1、利用DNSlog来测试漏洞是否存在2、加载恶意文件Exploit.java,将其编译成class文件3、开启web服务4、在恶意文件Exploit.class所在的目录开启LDAP服务5、监听反弹shell的…...
大数据Flink(八十一):SQL 时区问题
文章目录 SQL 时区问题 一、SQL 时区解决的问题...
网站代码输入完成之后要怎么做/爱用建站
导读:本文是matlab类有关专科毕业论文范文与MATLAB方面专科毕业论文范文.周子健张飞【摘 要】论文前半部分根据相关理念和相关概念设计出了直流调压调速控制系统的各个环节之间的联系以及各个部分的原部件.随后对这些原部件的参数进行了精确的计算,设计出了各个部分应该采用的相…...
大型网站建设企业/it培训机构
校正网络负责的是调整开环截止频率和相位裕度。(幅值裕度也会跟着相位裕度变大而变大) 1)比例环节Kp 偏差的比例 增益:可调整整个环节的增益,减小偏差。(不懂) 增加Kp会影响稳定性ÿ…...
网络营销薪酬公司/seo优化网站的手段
Git更新远程仓库代码到本地分支 一句代码解决 今天原本用的电脑被拿去维修了 换了另外一台电脑 刚好遇到这样一个问题 需要在新的这台电脑上把远程仓库上的代码拉下来 看了官方文档说用 git fetch 来实现 觉得挺麻烦的 发现了只用写一句命令就可以解决的方法 解决方案 使用 gi…...
电商建站系统/宁波seo推荐推广平台
解题思路:最短路的模板题,注意一个细节处理即可。 见代码: 1 #include<cstdio>2 #include<cstring>3 #include<algorithm>4 using namespace std;5 #define inf 0x3f3f3f3f6 const int maxn 1005;7 int vis[maxn], w[maxn][maxn], d[…...
如何做转发文章赚钱的网站/seo北京网站推广
这里是修真院前端小课堂,每篇分享文从 【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】 八个方面深度解析前端知识/技能,本篇分享的是: 【 css中content属性,有什么作用&a…...
jsp网站开发四 酷 全书源码/seo技术交流论坛
1、穿透 穿透:频繁查询一个不存在的数据,由于缓存不命中,每次都要查询持久层。从而失去缓存的意义。 解决办法: 持久层查询不到就缓存空结果,查询时先判断缓存中是否exists(key) ,如果有直接返回空,没有则查…...