JVM总结全

news2024/9/22 21:33:39

虚拟机

HotSpot 默认虚拟机

JRockit HotSpot融合了JRockit jdk8初步融合完成 没有解释器,只有编译器

IBM J9

结构图

在这里插入图片描述

在这里插入图片描述

类加载子系统Q

1.类加载器

​ 启动类加载器(引导类加载器)Bootstrap ClassLoader

​ 加载java 核心类库,没有父类加载器,只加载包名为java,javax,sun等开头的类

​ 扩展类加载器 Extension ClassLoader

​ 父类加载器为启动类加载器

​ 应用程序加载器 AppClassloader

​ 父类加载器为扩展类加载器,用户编写的类由它加载

​ 自定义类加载器

​ 想加载自己的class文件,需要自定义类加载器,也可以对class文件进行加密和解析,tomcat就有自己的自定 义类加载器

2.双亲委派机制

当类加载器加载一个class文件,类加载器不会立即加载,而是交给自己的父类加载,一直传递给启动类加载器,父类加载不了,再交给子类加载器加载。

作用:避免核心API被修改

3.沙箱安全机制

​ 自定义java.lang.String类(带main方法),加载自定义String类的时候由于双亲委派机制,会由启动类加载器加载,加载系统自带的String类,就会报错没有main方法,这就是沙箱安全机制

4.类加载过程

​ 一、加载阶段

​ 由引导类加载器,扩展类加载器,系统类加载器加载.class文件

​ 二、链接阶段

​ 链接阶段分为验证,准备,解析

​ 验证:是为了保证字节码文件的安全性

​ 准备:为类变量分配内存空间并初始化零值

​ 解析:将常量池的符号引用转换为直接引用(真实的地址)

​ 三、初始化阶段

​ 初始化主要是初始化类变量,执行方法,这个方法会自动按顺序收集所有类变量的赋值动作以及 静态代码快的语句,如果有父类,会先加载父类

运行时数据区

1.PC寄存器

​ PC寄存器线程私有,储存下一条指令的地址,由执行引擎读取。分支,循环,跳转,线程切换,异常都依赖寄存器完成。没有OutofMemoryError,内存占用忽略不计,是运行最快的区域。

2.虚拟机栈

​ 线程私有,由一个个栈帧组成。主管Java程序的运行,栈帧由局部变量表,操作数栈,动态链接,方法返回地址组成。如果固定大小,会抛出StackOverFlow 动态扩展会抛出OutofMemoryError

栈帧的运行原理

​ 每个栈帧对应一个方法,调用就入栈,方法结束就出栈,先进后出,后进先出。运行时,只有顶层 的栈帧是有效的,执行引擎只操作这个栈帧。当前栈帧调用新的方法,新的栈帧会被创建并压入栈顶成为有效栈帧,此栈帧调用结束后会出栈,前一个栈帧重新成为有效栈帧。方法的返回要么使用return指令返回,要么抛出异常,这两种情况该栈帧都会出栈。

局部变量表

​ 为一个数组,存储方法参数和局部变量,包括基本数据类型,对象引用,方法返回值。局部变量表编译器就被确定下来的。局部变量表只在当前方法中有效,栈帧出栈后就会被销毁。

  • Slot槽

​ Slot为局部变量表中的基本储存单元,每个Slot就是数组中的一个位置。32为的变量占用1个slot,包括对象引用,方法返回值,64位的占用2个slot,访问的时候通过第一个slot访问。构造方法,局部变量有序复制在slot上,如果当前方法为实例方法,下标为0的slot存放this。局部变量表是可达性分析算法GCRoot重要的根节点。

操作数栈

​ 操作数栈主要用于保存计算过程的中间结果,为计算过程中变量的临时储存空间。当一个栈帧被创建的时候,一个空的操作数栈也会一同被创建出来,栈的最大深度在编译期就已经确定下来了。操作数栈也是通过入栈和出栈完成数据的访问。

动态链接

​ 每个栈帧内部都包含一个执行运行时常量池中该栈帧所属的方法引用,持有这个引用是为了支持方法调用过程中的动态链接。class文件中的常量池符号引用,在链接阶段的解析过程中会把符号引用转换为直接引用,存到运行时数据区中。

方法返回地址

​ 方法返回有两种情况,一种通过return指令返回,另一种发生异常退出。前者方法返回地址会放入里,PC寄存器的值就是方法的返回地址,后者,需要通过异常表确定方法返回的位置。

​ 方法退出首先恢复上层方法的局部变量表和操作数栈,如果有返回值,把返回值压入操作数栈,执行引擎执行当前指令,调整PC寄存器指向下一条指令。

3.本地方法栈

同虚拟机栈,执行本地方法(native)

4.堆

​ 堆为虚拟机内存管理最大的一块区域,此区域唯一的目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,这里是垃圾收集器管理的主要区域。

堆的内存划分

在这里插入图片描述

年轻代和老年代默认比例1:2

Eden和S0,S1比例 8:1:1

对象分配的过程

1.new的新对象放在Eden区

2.Eden区满时触发Young GC,将Eden区的对象进行垃圾回收,销毁没有引用的对象,把没有回收的对象年龄加1放在To区(s1)

3.如果再次发生垃圾回收,把From区(s1)的对象和Eden区的对象进行垃圾回收,把没有回收的对象年龄加1放在To区(s2),谁空谁是To

4.在Young GC后如果对象的年龄等于15时,进入老年代

5.如果老年代的空间不足就会触发Full GC

Young GC、Major GC 和 Full GC

​ Young GC Eden和From区的垃圾回收,回收比较频繁,会发生STW

​ Major GC 为老年代的垃圾回收,只有CMS单独回收老年代

​ Full GC 老年代和方法区混合回收

Java堆分代的原因

​ Java对象有的存活时间短,有的存活时间长,不分代每次回收都扫描整堆,存活时间长的对象是没必要每次都扫描的。把朝生夕死的对象归为年轻代,存活时间长,大的对象归为老年代,这样就能提高垃圾回收的效率。 垃圾回收算法有标记清除,复制算法,标记整理,分代后对不同的区域使用不同的算法,发挥各自的优势。

逃逸分析,栈上分配

​ 当一个对象只在方法内部使用,则认为没有发生逃逸分析,在栈上分配一小块空间,可以把该对象分配到栈上,随着栈帧的弹出而一同销毁。

堆空间常用参数

-Xms 初始堆空间内存(默认为物理内存的1/64)

-Xmx 最大堆空间内存(默认为物理内存的1/4)

-Xmn 设置新生代的大小(初始大小,也是最大大小)

-XX:NewRatio:配置新生代和老年代的结构占比

-XX:SurvivorRatio 设置新生代中Eden和S区的空间占比

-XX:MaxTenuringThreshold 设置新生代S区对象最大年龄

-XX:PrintGCDetails 输出详细的GC处理日志

5.方法区

​ 方法区是Java虚拟机的规范,HotSpot的具体实现在jdk8之前叫永久代,jdk8及之后叫元空间。 永久代 在JVM中,元空间使用的是堆外内存,不在占用虚拟机的内存。方法区和堆一样是线程共享的区域。方法区存放类型信息,运行时常量池,静态变量,JIT代码缓存、域信息、方法信息。方法区的大小决定可以保存多少类,保存太多类型一样报OutofMemoryError.

方法区大小设置

jdk7以前:

​ -XX:PermSize=size 初始大小 默认20.75M

​ -XX:MaxPermSize 最大可分配空间 默认64位机器82M

jdk8及之后:

​ -XX:MetaspaceSize 默认21M

​ -XX:MaxMetaspaceSize 默认-1.没有限制

演进细节

在这里插入图片描述

字符串常量此为什么要移到堆区

​ 永久代的回收效率比较低,字符串的使用率比较高,生命周期短,回收比较频繁,但字符串在永久代中不能及时回收,永久代被字符串占满,就会触发Full GC,影响垃圾回收效率。移到堆中就能够及时回收。

方法区的垃圾收集

常量池中废弃的常量(易回收)和不再使用的类型(难回收)

执行引擎

是java虚拟机的核心组成部分。执行引擎(Execution Engine)的任务就是将字节码指令解释/编译为对应平台上的本地机器指令。

解释器

解释器会逐条解释PC寄存器的指令,将字节码指令翻译为对应平台的机器指令。

编译器

虚拟机将一段热点代码直接编译为本地机器平台相关的机器语言。

解释器和编译器的比较

由于解释器是逐条执行,执行效率低下,但响应速度快。编译器是将一段字节码指令直接编译位对应平台的机器码,编译需要时间,响应速度慢,执行速度快。解释器就是步行,想走就走,编译器的公交车,要等车来,坐上车速度起飞。

HotSpot虚拟机采用解释器和编译器并存,就是为了同时兼顾编译代码的时间和代码运行的时间。

热点代码及探测方式

​ JIT及时编译器不是所有的代码都会编译为机器码,是有选择的编译热点代码。一个调用多次的方法或方法体内部循环较多的循环体称为热点代码。JVM设定了一个阈值,达到这个阈值JIT编译器就会把这段代码编译为机器码存放在元空间中。用于统计调用次数的算法有两种:方法调用计数器和回边计数器。方法调用计数器用于统计方法的调用次数。回边计数器则用于统计循环体执行的循环次数。

字符串常量池

String基本特性

声明:String s1 = “hello” Stirng s2 = new String(“hello”)

String 声明为final,不可被继承,值不可变

String实现了Serializable接口,表示字符串支持序列化

String实现了Comparable接口,表示String可以比较大小

String jdk8以前底层是char[] jdk9是byte[] 节省储存空间

String的字符串常量池

String pool 是一个HashTable,默认长度为1009,如果放入的String非常多,会造成hash冲突严重,会造成链表非常长(jdk8会转红黑树)调用String.intern()方法时的效率低下

在jdk7中,StringTable的长度默认值是60013

jdk8开始,1009是StringTable长度可设置的最小值

StringTable的存放位置

jdk6及之前,字符串常量池存放在永久代

jdk7后,字符串常量池移到了堆里

StringTable调整的原因

永久代的空间比较小,字符串在程序中比较常见,永久代垃圾回收频率低,移到堆中提高回收频率

字符串拼接

常量与常量拼接结果在常量池,编译器优化

拼接的字符串中有一个是变量,拼接的原理就是StringBuilder

StringBuilder的toString()方法

在new String(“aa”) 时创建了两个对象

StringBuilder的toString()方法创建了一个对象,没有加入字符串常量池

String的intern()

jdk1.6

如果字符串常量池中有,则并不会放入。返回已有的串池中的对象的地址

如果没有,会把此对象复制一份,放入串池,并返回串池中的对象地址

jdk1.7

如果字符串常量池中有,则并不会放入。返回已有的串池中的对象的地址

如果没有,则会把对象的引用地址复制一份,放入串池,并返回串池中的引用地址

垃圾回收

标记阶段

​ 在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为垃圾标记阶段。

引用计数算法

对每个对象保存一个整型 的引用计数器属性。用于记录对象被引用的次数。无法处理循环引用的问题。

可达性分析算法

​ 以根对象集合为起始点,递归搜索根集合所连接的对象是否可达。如果对象不可达该对象就是要回收的对象。

GC Root

​ 虚拟机栈中引用的对象 、本地方法栈引用的对象、类变量引用的对象、 方法区中常量引用的对象 、所有被同步锁synchronized持有的对象、虚拟机内部的引用

清除阶段

标记-清除算法

​ 有效内存被耗尽时,停止整个程序(STW)。先进行标记,从根节点递归遍历标记被引用的对象。然后线性遍历,清除没有标记的对象。

​ 效率不高,清理后内存空间不连续,易产生内存碎片。

复制算法

​ 将内存空间分为两块,每次只用其中的一块。标记阶段标记被引用的对象。然后把有引用的对象复制到另一块中。

​ 这种方法不会产生内存碎片,但要用两倍的空间。由于对象的地址改变了,需要维护引用关系。而且存活对象特别多,复制起来效率会很低。

标记-压缩(整理,Mark-Compact)算法

​ 先进行标记,从根节点递归遍历标记被引用的对象。然后所有存活的放在内存的一端,按顺序排放。之后清理边界外的所有空间。解决了标记清除算法的空间碎片问题。

垃圾回收器

评估GC的性能指标
  • 吞吐量 : 运行用户代码的时间占总运行时间的比例

垃圾收集开销 :垃圾收集时间占总运行时间的比例

  • 暂停时间:执行垃圾收集时,程序工作线程被暂停的时间

收集频率: 相对于程序的执行,收集操作发生的频率

  • 内存占用:java堆所占内存的大小

三者共同构成一个“不可能三角”。三者总体的表现会随着技术进步而越来越好。一款优秀的收集器通常最多同时满足其中的两项。

7款经典的垃圾收集器与垃圾分代之间的关系

新生代收集器: Serial、 ParNeW、Parallel Scavenge;

老年代收集器: Serial 0ld、 CMS、Parallel 0ld;

整堆收集器: G1

Serial回收器:串行回收

ParNew回收器:并行回收

CMS回收器:低延迟

G1回收器:区域化分代式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/61221.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT + FFmpeg 5.x + x264 + x265 + SDL2 音视频播放器

QT FFmpeg 5.x x264 x265 SDL2 音视频播放器 使用了QT的QML设计界面,人机交互; 使用了FFmpeg 5.x x264 x265 SDL2 完成了音视频的解析到播放; 阅读了ffplay的源码,用到了ffplay的核心思想. 想熟悉ffmpeg和ffplay的朋友,都可以参考学习. 代码自取: https://github.c…

秒杀实现技巧

需求分析 “秒杀”这个词在电商行业中出现的频率较高,如京东或者淘宝平台的各种“秒杀”活动,最典型的就是“双11抢购”。 “秒杀”是指在有限的时间内对有限的商品数量进行抢购的一种行为,这是商家以“低价量少”的商品来获取用户的一种营…

Golang原理分析:切片(slice)原理及扩容机制

《Go语言精进之路》切片相关章节学习笔记及实验。 1.切片原理 说切片之前,先看看Go语言数组。Go数组是一个固定长度的、容纳同构类型元素的连续序列,因此Go数组类型具有两个属性:长度及类型: var a [1]int var b [2]byte var c …

【Web安全】文件上传漏洞

目录 1. 文件上传漏洞概述 1.1 FCKEditor文件上传漏洞 1.2 绕过文件上传检查功能 2. 功能还是漏洞 2.1 Apache文件解析 2.2 IIS文件解析 2.3 PHP CGI路径解析 2.4 利用上传文件钓鱼 3. 设计安全的文件上传功能 1. 文件上传漏洞概述 文件上传漏洞是指用户上传了一个…

R语言学习笔记——入门篇:第四章-基本数据管理

# R语言R语言学习笔记——入门篇:第四章-基本数据管理 文章目录一、示例二、创建新变量三、变量的重编码四、变量的重命名4.1、交互式编辑器4.2、函数编程五、缺失值5.1、重编码某些值为缺失值5.2、在分析中排除缺失值六、日期值6.1、将日期值转换回字符型变量6.2、…

使用 Learner Lab - 在 Lambda 建立 Pillow 层,进行 S3 的图片镜相操作

使用 Learner Lab - 在 Lambda 建立 Pillow 层,进行 S3 的图片镜相操作 AWS Academy Learner Lab 是提供一个帐号让学生可以自行使用 AWS 的服务,让学生可以在 100 USD的金额下,自行练习所要使用的 AWS 服务,如何进入 Learner La…

[论文阅读] 颜色迁移-Automated Colour Grading

[论文阅读] 颜色迁移-Automated Colour Grading 文章: Automated colour grading using colour distribution transfer, [paper], [matlab代码], [python代码] 1-算法原理 本文算法分为2个大步骤, 首先使用IDT(Iterative Distribution Transfer)方法得到初步的结果, 这个结果…

优雅的springboot参数校验(二)

7. 集合校验 有这样一种场景,前端请求后端接口时,需要传递的是一个数组,数组的元素是一个对象,并且希望后台收到参数后可以对数组集合中的元素元素对象的属性进行校验,如果后台直接以List的来接收参数,约束…

[附源码]计算机毕业设计基于springboot的云网盘设计

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

linux网络编程之tcp

相关函数 int socket(int domain,int type,int protocol);参数: domain: AF_INET AF_INET6 AF_UNIX,AF_LOCAL AF_NETLINK AF_PACKET type: SOCK_STREAM: 流式套接字,唯一对应于TCP SOCK_DGRAM:数据报套接字,唯一对应着…

【第七章 MySQL体系结构、存储引擎、InnoDB、MyISAM、Memory、存储引擎特点及选择】

第七章 MySQL体系结构、存储引擎、InnoDB、MyISAM、Memory、存储引擎特点及选择 1.MySQL体系结构: ①连接层: 最上层是一些客户端和链接服务,包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连…

[Power Query] 日期和时间处理

Power Query查询编辑器为日期和时间数据提供了强大而快捷的处理方式 例1: 从日期中提取年、月份、日、季度、周、天等信息 数据源 步骤1:将数据源导入到Power BI Desktop,单击【转换数据】选项,进入Power Query查询编辑器界面 步骤2:选中"日期&qu…

【概念】数据仓库和数仓建模

数据仓库 数仓主要特征 面向主题:每个需求和表都属于一个主题,可以用主题来对数仓的表分门别类集成性:将异构数据源,比如MySQL和服务器埋点日志,统一转换成结构化的hive表数据存储到ODS层非易失性:对历史…

Flink系列文档-(YY12)-窗口计算

1 窗口基本概念 1.1 概述 窗口,就是把无界的数据流,依据一定规则划分成一段一段的有界数据流来计算; 既然划分成有界数据段,通常都是为了"聚合"; Keyedwindow重要特性:任何一个窗口&#xff0…

游戏开发36课 cocoscreator scrollview优化

在cocoscreator内,ScrollView控件封装的挺完美的了,不过对于一些对性能要求比较高的场景,会存在问题,以top100排行榜排行榜举例子 1、应用卡顿甚至崩溃 按照官方用例使用ScrollView,插入100个玩家的item,理…

离线安装harbor容器镜像仓库(harbor-v2.3.5)

记录:354 场景:在CentOS 7.9操作系统上,离线部署harbor容器镜像仓库集群,使用Redis为外部缓存、使用PostgreSQL为外部数据库、使用Ceph为共享存储、使用nginx为harbor的负载均衡、使用Keepalived为集群高可用、使用docker-ce操作…

【专业术语】(计算机 / 深度学习与目标检测 / 轨道交通)

专业术语-计算机 / 深度学习与目标检测 / 轨道交通一、 计算机1 IDE2 API3 CUDA Driver API3.1 cuInit - 驱动初始化3.2 关于context,有两种:3.3 CUcontext4 RuntimeAPI5 Memory5.1 关于内存,有两大类:5.1.1 CPU内存,称…

[附源码]Python计算机毕业设计Django考试系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

FISCO BCOS(二十五)———多机部署

一、基础环境搭建 1、查看当前是否安装了ssh-server服务 dpkg -l | grep ssh2、安装ssh-server服务 sudo apt-get install openssh-server3、修改配置文件"/etc/ssh/sshd_config" 4、重启openssh-server root@FISCOBCOS01:~# sudo /etc/init.d/ssh restart5、查看…

高数 |【2020数一真题】部分错题及经典题自用思路整理

T1:积分限与被积函数都等价为无穷小 T2:不连续一定不可导 T3:可微的定义 T4:收敛半径 T6:空间直线与向量 法一: