JVM重点整理

news2025/1/10 18:47:17

一、虚拟机架构图

在这里插入图片描述

二、类加载过程

在这里插入图片描述
类加载器的作用:负责把class文件加载到内存中

类加载过程:

  • 加载:
    • 通过类的全限定名获取此类的二进制字节流
    • 文件的编码结构---->运行时的内存结构
    • 内存中生成一个class对象
  • 链接:
    • 验证:保证被加载类的一个正确性
    • 准备:为类变量分配内存 设置类变量初始值(不会为final修饰的变量以及实例变量赋值)
    • 解析:相当于一个翻译过程
  • 初始化: 初始化阶段执行类加载方法() 的过程,()不同于类的构造器。若该类具有父类,JVM 会保证子类的()执行前,父类的该方法已经执行完。多线程下被同步加锁。

三、类加器的分类

在这里插入图片描述

  • 虚拟机自带的类加载器:
    • 启动类加载器:由c/c++语言实现,嵌套在JVM内部,不继承自java.lang.ClassLoader,没有父加载器,只加载java、javax、sun等开头的类
    • 扩展类加载器:派生于ClassLoader类,父类加载器为启动类加载器。
    • 应用类加载器:默认的类加载器,一般来说,java应用的类都是由它完成加载。派生于ClassLoader类,父类加载器为扩展类加载器。通过ClassLoader.getSystemClassLoader()方法获取该类加载器。
    • 自定义类加载器:
      • 好处:隔离加载类
      • 修改类加载的方式
      • 扩展加载源
      • 防止源码泄露

双亲委派机制:
在这里插入图片描述
在这里插入图片描述
好处: 避免类的重复加载、保护程序安全,防止核心API被篡改。
沙箱安全机制: 保护原生JDK的安全。

四、内部结构

1、PC 寄存器: 用来存储下一条即将执行的指令地址,指令由执行引擎执行。
使用PC寄存器存储字节码指令地址有什么用?/ 或为什么使用PC寄存器记录当前线程的执行地址?
因为CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行。

2、本地方法:(native修饰的)与java环境外交互、与操作系统交互。本地方法栈:用来管理本地方法的结构 线程私有
3、虚拟机栈:
概念:栈是运行时的单位、栈解决程序运行时的问题,即程序如何执行,或者如何处理数据。
栈帧:一个内存区块,栈中数据以栈帧格式存在,每个方法对应一个栈帧。
在这里插入图片描述
局部变量表:存储方法参数和定义在方法体内的局部变量,数组结构,建立在线程的栈上,线程私有不存在数据安全问题。容量大小在编译期就已确定,随栈帧的销毁而销毁。
运行原理:先进后出
4、堆空间
概述:

  • 一个JVM实例对应一个进程实例,一个JVM实例有一个运行时数据区。
  • 一个Runtime就有一个独立的方法区和堆
  • 一个进程有多个线程,多个线程共享一个方法区和堆空间
  • 一个线程拥有自己独立的程序计数器、本地方法栈、虚拟机栈
  • 为了解决多个线程访问出现线程不安全问题—>TLAB(线程私有空间)
  • 垃圾回收只会在堆(方法区)当中进行回收

堆内存细分:
基本划分:新生代+老年代+元空间
比例:新生代:老年代=1:2
新生代=Eden:from:to=8:1:1
创建对象在Eden区

内存分配策略

  • 默认对象分配在Eden区
  • 如果一个对象回收超过阈值次数还存活就把它放入老年代
  • 大对象分配在老年代
  • 对于体积不大的对象优先分配在Eden区的TLAB区
  • 对象还有可能分配在栈空间

TLAB区(Thread Local Allocation Buffer)

为什么要有该区域?
	堆空间是线程共享的区域,在高并发的场景下分配内存空间,会出现线程不安全的问题,采用加锁虽然可以避免此问题但是会影响效率。
	TLAB是线程私有的一块区域,即使多个线程同时分配也不会有线程安全的问题,提高吞吐量,快速分配,JVM会将TLAB作为内存分配的首选

五、逃逸分析
1、为什么存在逃逸分析
如果对象在堆内存分配–可能引起GC–导致STW–应用程序卡顿,而逃逸分析可以减少此类现象的发生
2、什么情况在栈上分配
如果一个对象没有发生逃逸,就可以在栈上分配,随着方法的结束对象的出栈,不涉及GC有效提高性能
3、判断对象是否发生逃逸
new出来的对象是否被外部方法调用,调用了就代表逃逸了。新建对象尽量是局部变量
4、逃逸分析目前还不是很成熟
六、方法区(元空间)
线程共享的区域,此区域大小决定了系统可以加载多少个类
堆栈方法区三者的关系:
在这里插入图片描述
内部结构:

  • 类的信息:类、接口、枚举等
  • 域信息:包的public、protected、private等
  • 方法信息:方法名称、返回类型
  • 常量信息
  • 静态变量/类变量

方法区的垃圾回收:
必要又难以让人满意,主要回收常量池里面不常使用常量和类型

七、垃圾回收

垃圾:在程序运行过程中没有任何指针指向该对象
意义: 不进行垃圾回收内存迟早会消耗完,导致其他对象无法分配内存,没有GC则无法保证应用程序的正常进行。
回收区域: 只有方法区和堆、频繁收集新生代、较少收集老年代、基本不动元空间/方法区

八、垃圾回收算法

判断对象是否存活的两种算法:引用计数法和可达性分析算法
1、引用计数算法
对于一个对象被引用则加1,引用失效就减1,当计数器为0时则表示该对象为垃圾。
缺点:无法解决循环依赖的问题
在这里插入图片描述
2、可达性分析算法:
以根对象为起始点从上往下搜索根对象所链接的对象是否可达,搜索走过的路径被称为引用链,不可达对象称为垃圾,
判定一个对象是否可回收,至少要经历两次标记过程。
在这里插入图片描述
GC Roots包含元素

  • 方法区中常量引用对象
  • 同步sync关键字持有的对象
  • 静态类变量

3、标记清除算法
在这里插入图片描述

标记: 从引用根节点开始遍历,标记所有被引用的对象。一般是对象的header中记录为可达对象
清除: 从头到尾进行遍历,如果某个对象在其header中没有标记为可达对象,则将其回收,清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表,下次有新对象需要加载时,判断垃圾的位置空间是否够,如果够就存放。
缺点: 产生空间碎片,还需要维护一个空闲列表
4、标记压缩算法(老年代)

在这里插入图片描述
缺点:移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址,移动过程中,需要全程暂停用户应用程序即STW。
5、复制算法(新生代)
核心思想:将活着的内存空间分为两块,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收。

在Eden区空间用完并且程序需要再创建对象时触发Minor GC 在GC后,如果对象仍然存活,将会被移到Survior区。
在这里插入图片描述
再次触发GC的时候Eden区和from区两者会作为回收区域
在Eden和from回收存活的对象复制到to之后要做三件事情
1、清空Eden和from区
2、把原先from变为to原先to变为from
3、对象d年龄加1(年龄达到设定值—>老年代)
在这里插入图片描述
优点:没有标记和清除过程,高效、不会产生空间碎片
缺点:需要两倍活着对象的空间大小
6、分代回收算法
新生代和老年代回收算法
7、增量回收算法
垃圾收集线程每次只收集一部分空间,接着切换到应用程序,反复执行,可避免长时间STW
缺点:线程来回切换造成上下文开销,降低吞吐量
8、分区回收算法
把一个内存区域划分为多个内存空间,每次只回收若干小区域内存
9、总结
没有最好的回收算法,只有最合适的,目前用的最多的是复合算法

九、MinorGC/MajorGC/FullGC的对比

a.MinorGC
只回收新生代
新生代空间不足的时候,该区域有个特点 对象大部分是朝生夕死
会触发STW 暂停其他用户线程 垃圾收集结束 用户线程才恢复
b.MajorGC
回收老年代
回收速度比MinorGC慢10倍以上 STW时间更长
c.FullGC
回收整个堆与方法区
更应该尽量避免

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

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

相关文章

LangChain大型语言模型(LLM)应用开发(五):评估

LangChain是一个基于大语言模型(如ChatGPT)用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互&#x…

【状态估计】基于UKF法、AUKF法、EUKF法电力系统三相状态估计研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【PHP面试题40】能够使HTML和PHP分离开使用的模板技术有哪些

文章目录 一、前言二、模板技术的好处三、常用的模板技术3.1 PHP模板引擎3.2 前端模板引擎3.3 前后端分离技术 四、Smarty模板使用演示4.1 在项目中引入Smarty模板引擎的文件4.2 引入Smarty.class.php文件4.3 创建一个Smarty对象4.4 变量定义4.5 创建一个Smarty模板文件4.6 绑定…

【C语言】念数字

问题描述: 输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出fu字。 输入格式: 输入在一行中给出一个整数, 如:1234。 提示:整数包括负数、零和正数。 输出格式: 在一…

【C语言】2-C 语言程序构建过程以及 C 语言的程序结构

1. 程序构建过程 1.1 什么是计算机语言 1.1.1 机器语言 计算机只能识别二进制,也就是说只能识别由 0 和 1 组成的指令。在计算机发展的初期,一般计算机的指令长度为 16,即用 16 个二进制数(0 或 1)组成一条指令,16 个 0 和 1 可以组成各钟排列组合。例如用 0011 1100…

Cyclo(RRRRRRR) , NP213 TFA,多肽合成,碱性侧链氨基酸

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ -----产品描述---- 环肽试剂Cyclo(RRRRRRR),属于7个精氨酸的多肽合成,碱性侧链氨基酸这些保护基在合成过程中稳定,无副反应,合成结束后可以完全定量的脱除。 -----试剂信息--…

基于C语言的学生成绩管理系统

(꒪ꇴ꒪ ),hello我是祐言博客主页:C语言基础,Linux基础,软件配置领域博主🌍快上🚘,一起学习!送给读者的一句鸡汤🤔:集中起来的意志可以击穿顽石!作者水平很有限,如果发现错误&#x…

jmeter命令行运行(非GUI形式)参数详解

目录 一、JMete执行方式 二、JMete非GUI运行优点 三、jmeter非GU运行参数 四、jmeter非GUI运行命令 4.1非GUI基本命令格式: 4.2非GUI并生成html报告基本命令格式 总结: 一、JMete执行方式 正常情况下我们会以有页面的方式打开jmeter编写接口&…

lvs使用

1.前言 LVS(Linux Virtual Server)是一个基于 Linux 内核的负载均衡器,用于分发网络流量和将请求转发给后端服务器。LVS 提供了多种负载均衡算法和转发模式,以满足不同场景和需求的负载均衡需求 2.lvs功能 LVS 提供了三种负载均…

React在Dva项目中创建并引用页面局部组件

这篇文章我们演示Dva中编写组件的方式 官方这里也特意强调了UI这个关键词 跟多是作为我们界面元素的组件 而不是页面路由 我们要单独做路由的组件肯定还是直接放在我们Dva项目的src下的routes目录下就好了 然后 我们看 项目 src下有一个 components 目录 一般我们做什么前端项…

连接区块链节点的 JavaScript 库 web3.js

文章目录 前言web3.js 介绍web3.js安装web3.js库模块介绍连接区块链节点向区块链网络发送数据查询区块链网络数据 前言 通过前面的文章我们可以知道基于区块链开发一个DApp,而DApp结合了智能合约和用户界面(客户端),那客户端是如…

TCP三次握手、数据传输与四次挥手

一、建立TCP连接 —— 三次握手 (1)客户端向服务端发送一个携带初始序列号的SYN包。 (2)服务端收到后将其加入到半连接队列,然后向客户端回复携带初始序列号的SYNACK包。 (3)客户端收到后再向服…

ModelAttribute用法详解

目录 官方解释 例子 使用场景1 使用场景2 场景3 官方解释 首先看一下官方文档上该注解的解释: 可以看到ModelAttribute可以用在参数上,也可以用在方法上: Can be used to expose command objects to a web view, using specific attribu…

ceph--cephFS的使用

ceph分布式存储—cephFS的使用 1、cephfs的概念 ceph FS 即 ceph filesystem,可以实现文件系统共享功能,客户端通过 ceph 协议挂载并使 用 ceph 集群作为数据存储服务器。 Ceph FS 需要运行 Meta Data Services(MDS)服务,其守护进程为 ceph-mds&#x…

【Unity面试篇】Unity 面试题总结甄选 |Unity渲染Shader相关 | ❤️持续更新❤️

前言 关于Unity面试题相关的所有知识点:🐱‍🏍2023年Unity面试题大全,共十万字面试题总结【收藏一篇足够面试,持续更新】为了方便大家可以重点复习某个模块,所以将各方面的知识点进行了拆分并更新整理了新…

怎样优雅地增删查改(六):按任意字段关键字查询

文章目录 实现应用测试 实现 定义按任意字段关键字查询过滤器(IKeywordOrientedFilter)接口,查询实体列表Dto若实现该接口,将筛选指定的目标字段(TargetFields)包含指定的关键字(Keyword&#…

软件开发的六大设计原则

我们常说软件开发要尽量具有良好的可扩展性,做到高内聚低耦合。那么究竟该如何实现呢?在面向对象软件设计领域有一系列大家所认可的设计原则,依据这些原则来设计软件,就可以让软件有很好的可扩展性,其中最重要的一条原…

发起投票平台投票吧网络投票平台网络投票平台

小程序投票活动如何做?很多企业在运营当中,都会通过投票活动来进行推广,从而达到吸粉、增加用户粘度等效果。而此类投票活动,通过小程序就可以实现,操作简单。 我们现在要以“青春大不同”为主题进行一次投票活动&…

扩展欧几里得 证明及应用代码(超详细,附带例题)

应用方面: 1.求解乘法逆元 2.求解(ax)%bc 即 a个x 模上b后得到c,其中满足条件的x的最小整数。[也可表示为axc(mod b)] 3.求解直线上的整点数 模板代码: 代码1: ll exgcd(ll a,ll b,ll &x,ll &a…

jeecgboot:vue3版本打包失败的解决过程

根据jeecgboot vue3的文档,把本地node升级到16,在本地运行都正常,打包后一直提示内存不足。 首先怀疑是代码配置问题,找到提示对应的地方,修改了package.json,把默认的NODE_OPTIONS--max-old-space-size81…