全网最好的JVM总结:有生命周期的JVM

1.编译

1.1 java中编译器有哪些?

  • 前端编译器 javac
  • 后台即时编译器 JIT编译器
  • 静态提前编译器 (一步到位,直接把java编译成二进制)

2.2 编译过程是怎么样?

  1. 解析与填充符号表,生成语法树 (编译原理的东西)
  2. 插入式注解处理器的处理过程,对语法树进行操作 (jvm提供了一些钩子方法对语法树进行修改)比较有名的lombok、阿里的checkStyle
  3. 字节码生成

2.3 解释器和编译器怎么搭配使用的?

  1. 当虚拟机启动之后,解释器根据预定义的规范对字节码逐行解释,解释生成对应平台的机器码
  2. 后台编译器在运行过程中,对代码进行不断的优化,常见的优化有:方法内联、去虚拟化、栈上分配
  3. 为什么要2个搭配使用?随着程序启动,解释器可以首先发挥作用,而不是等后台编译器全部编译完再执行,即时编译器后期再慢慢优化

2.字节码

2.1 字节码长什么样?

  1. 咖啡baby
  2. 大版本+小版本
  3. 常量池:常亮池中的内容大致可以这么理解:
    1. 用utf-8 info这个类型来表示字节码,比如 private Integer i 用2个utf-8 info类型 Integer、i,
    2. 然后各种属性类型、方法类型来引用这个utf-8Info, 比如 field_info 指向前面2个utf-8 info类型
  4. 属性表集合
  5. 方法表集合

image.png

2.2 字节码怎么玩

image.png

  • ASM派 ASM => Byte Buddy =>cglib
  • Javassist派 Javaassist

JDK、CGLIB、Javassist和ASM的动态代理使用对比_xiaoliuliu2050的博客-CSDN博客

3.类加载

3.1 类加载的来源

  1. 文件
  2. 网络
  3. 动态代理

3.2 类加载的过程

  1. 加载
  2. 链接
    1. 验证 验证这个类文件对不对
    2. 准备 给类变量赋初值
    3. 解析 将运行时常量池里面的符号引用转换为直接引用
  3. 初始化
  4. 使用
  5. 卸载

!!! 解析和初始化的顺序不是确定的,为了动态绑定,先初始化,再解析

3.3 哪些情况会进行类的初始化

  1. 使用new
  2. getStatic、putStatic、invokeStatic这几条字节码指令,就是说我想要操作类变量的时候,不管是属性还是方法,都会导致类加载
  3. 对类进行反射调用
  4. 初始化类的时候,如果父类没有初始化,需要初始化父类
  5. 虚拟机启动时,用户需要指定一个执行的主类(main),虚拟机就会初始化这个类

3.4 类加载和类初始化的理解

类加载不代表类初始化了,类初始化就代码类肯定加载了。XXX.class就只是加载了类,但是并没有类初始化。

3.5 几个类加载

  1. Bootstrap ClassLoader 加载核心类库,rt.jar
  2. Extension ClassLoader 拓展类加载 /jre/ext/xxx.jar
  3. Applicaiton ClassLoader 系统类加载 加载ClassPath上的类
  4. 自定义加载器

3.6 为什么要使用双亲委派

保证核心类库的安全

4.运行时数据区 jvm | ProcessOn免费在线作图,在线流程图,在线思维导图 |

image.png

4.1 方法区

4.1.1 方法区的理解

在类加载之后,把字节码静态数据转换为运行时的数据结构,比如常量池->运行时常量池;常量池之后的类、方法、属性啊 ->上图中的类信息、属性、方法信息等;另外在堆中创建一个Class对象作为方法区的入口



4.2.2 方法区存放哪些内容

  • 运行时常量池
  • 类信息 (类、属性、方法)

4.2.3 方法区的演进过程

image.png

  • 在1.8之前称为永久代,里面存放的 运行时常量池(包含字符串常量池)、类信息、静态变量等
  • 1.8之后换为元空间,将静态变量、字符串常量池放到堆里面
  • 为什么把永久代换成元空间,随着各种动态加载框架的使用,永久代空间设置很难确定,那么我们是不是可以放到jvm内存之外来分配哪,用元空间就解决了这个问题

4.2 堆

4.2.1 堆的组成结构

  • 新生代
    • Eden区
    • Survivor区
    • Eden:Survivor1: Survivor2 = 8:1:1
  • 老年代

4.3 虚拟机栈

1个线程就有1个虚拟机栈,线程方法调用就是栈帧的入栈和出栈

4.3.1 栈帧里面有什么

  • 局部变量表
  • 操作数栈 :局部变量表通过操作数栈来完成一些运算
  • 动态链接:多态的时候,想要知道这个方法到底属于哪个类的方法,所以栈帧会有一个指向运行时常量池的方法引用
  • 返回地址:存放调用方法的pc寄存器的值,我得知道上一个方法地址是多少

4.4 本地方法栈

在hotspot中,本地方法栈和虚拟机栈实现方式一样,本地方法栈调用的都是native方法

4.5 程序计数器

唯一不会出现OOM的内存区域

4.6 对象的创建过程

Car car = new Car(); car.start();

  1. 类加载:当遇到new指令时,虚拟机检查Car能否在运行时常量池中定位到它的符号引用,如果没有,那就进行类加载,结果:将类加载进方法区,堆生成一个Class对象,方便访问
  2. 对象内存分配:给对象分配一块内存,分配出现并发问题解决方案:1、CAS自旋 2、TLAB 本地分配(在eden中给每个线程分配了一块内存),结果:在Eden区中分配一块内存给Car对象
  3. 对象内存初始化:Jvm初始化分配好的内存,将其设为零值。结果:Car对象的实例都是有初始数据的
  4. **设置对象头: **1、设置markword(hashcode、GC分代年龄、锁标志、锁信息)2、设置类型指针(指向堆里面的class对象)

image.png
image.png

  1. **执行构造函数:**最后执行构造函数,对属性赋值。
  2. **Car引用指向 Car对象:**这里引用有哪些?强软(内存不够回收)弱(gc回收)虚 (随时可能回收)
  3. **创建栈帧入栈:**创建start栈帧入栈

5. GC

创建完对象,系统开始运行起来了,但是随着越来越多的对象创建并执行,内存是不是不够了,内存不够怎么办,那就是垃圾回收

5.1 怎么知道哪些对象要回收

  • 引用计数法 :可能存在循环引用,导致gc不了的问题
  • 可达性分析算法:在hotspot中使用的是可达性分析算法,从GC Roots往下往下开始遍历,看GC Roots上有没有对象引用到它,如果没有,就考虑要回收了

5.2 GC Roots哪些

  • 局部变量
  • 静态变量

5.3 怎么回收(算法)

  • 复制算法

将内存一分为二,在同一时间只会使用其中一块内存,GC的时候只要标记出存活对象,然后把存活对象移到另外一半内存中就行

  • 优点:简单快速、内存完整

  • 缺点:内存利用率低

  • 标记清除

    GC的时候标记出所有存活对象,然后把没有标记的对象全部清理掉

    • 优点:简单
    • 缺点:会产生大量的内存碎片
  • 标记整理

GC的时候标记出所有存活对象,然后把没有标记的对象清理掉,并将存活对象挪到到内存一端。

  • 优点:内存完整
  • 缺点:效率不是很高

5.4 怎么回收(实践)

有了算法,当然有对应的垃圾回收器,比如Serial、ParNew、ParallelScavenge、CMS、G1等等。
根据新生代和老年代的特点,最终是这样的:
image.png

  • 新生代 朝生夕灭,存活对象不多,所以使用复制算法
  • 老年代 对象存活对象比较多,所以使用整理或者清除算法

新生代:Serial 单线程、ParNew 多线程、Parallel 吞吐量
老年代:SerialOld 单线程、 Paralle Old、CMS

一般来说,内存小一点的用 parNew + cms, 内存大一点的就直接上g1了

5.5 CMS的工作原理

  1. 初始标记 简单的找一下 GC Roots
  2. 并发标记 GC线程和用户线程并发执行,从GC Roots开始标记需要清理的对象
  3. 重新标记 在并发执行的时候,肯定又会产生很多垃圾,所以需要重新标记需要清理的对象
  4. 并发清理 将需要清理的对象全部清理掉

也就说它把stop world处理的时间分散在和用户线程并发处理中了

5.6 CMS可能会出现的一些问题

  • CMS老年代垃圾回收的默认触发比例是92%,也就是说92%的时候会触发老年代回收,如果在并发清理的时候,又有对象进入老年代,假设老年代不够,就会使用Serial Old去Stop World来回收老年代所有对象,一旦使用Serial Old来回收内存,非常的耗时
  • CMS使用的标记清除,会存在内存碎片,所以CMS给了参数CMS的另外一个参数 -XX:+UseCMSCompactAtFullCollection,就是说在几个Full Gc之后需要执行一次内存碎片整理的

5.6 G1的工作原理

  • G1会把内存分为很多Region,默认是2048个,假设设置堆内存4G,那就是每个Region2M
  • 新生代初始占比5%,也就是大概100个region,接着JVM会不断增加Region,但是不会超过60%
  • 尽管G1取消了新生代、老年代,但是其实对于Region来说还是有逻辑的分代思想
  • 新生代里面还有Eden和Survivor,默认也是8:1:1。在创建Eden的同时也会创建Survivor。
  • 当新生代Region超过 60%,就触发垃圾回收,会把Eden的Region放到S1中Region中,不过在回收的时候需要考虑停顿时长200ms,如果设置了,就需要保证回收时长不能大于200ms
  • Region里面的新生代慢慢也会存放到老年代中

5.7 三色标记

  • 初始状态对象都是白色
  • CMS和G1在初始标记的时候,GC Roots 标记为灰色
  • 并发标记的时候,扫描整个引用链,有子节点的话,当前节点标记为黑色,子节点为灰色
  • 重复上面的过程,最后

image.pngA D2个是灰色
image.pngAD 2个变成黑色,E是灰色
image.pngEFG变成黑色,清理白色 BCH

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计模式学习笔记 - 设计模式与范式 -行为型:17.中介模式:什么时候用中介模式?什么时候用观察者模式?

概述 本章学习 23 种经典设计模式中的最后一个设计模式,中介模式。和之前讲过的命令模式、解释器模式类似,中介模式也不怎么常用,应用场景比较特殊、有限,但是,跟它俩不同的是,中介模式理解起来并不难&…

Linux部署自动化运维平台Spug

文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台,整合了主机管理、主机批量执行、主机在线终端、文件…

【深度学习】多层感知机与卷积神经网络解析

引言: 在人工智能的宏伟画卷中,深度学习如同一笔瑰丽而深邃的色彩,为这幅画增添了无限的生命力和潜能。作为支撑这一领域核心技术的基石,多层感知机(MLP)和卷积神经网络(CNN)在模仿人…

文心一言 VS 讯飞星火 VS chatgpt (236)-- 算法导论17.3 2题

二、使用势能法重做练习17.1-3。练习17.1-3的内容是:假定我们对一个数据结构执行一个由 n 个操作组成的操作序列,当 i 严格为 2 的幂时第 i 个操作的代价为 i ,否则代价为1。使用聚合分析确定每个操作的摊还代价。如果要写代码,请…

【漏洞复现】泛微E-Mobile 6.0 client.do存在命令执行漏洞

0x01 阅读须知 “如棠安全的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供…

关于Salesforce DevOps的理解

“DevOps”是一组结合了软件开发 (Dev) 和运营 (Ops) 的实践,可帮助团队更快、更可靠地构建、测试和发布软件。 DevOps 的核心理念包括持续集成(Continuous Integration)、持续交付(…

Docker+Nginx部署vue项目

这篇文章给大家分享一下如何使用DockerNginx部署前端vue项目。 第一步:创建vue项目 执行这个命令,创建一个vue项目 npm create vue3将vue项目打包 npm run build此时会看到vue工程中生成了一个dist文件,我们将他上传到服务器中。 第二步…

步骤大全:网站建设3个基本流程详解

一.领取一个免费域名和SSL证书,和CDN 1.打开网站链接:https://www.rainyun.com/z22_ 2.在网站主页上,您会看到一个"登陆/注册"的选项。 3.点击"登陆/注册",然后选择"微信登录"选项。 4.使用您的…

VMware Workstation部署最新版OpenWrt 23.05.3

正文共:1456 字 51 图,预估阅读时间:2 分钟 我们之前介绍了如何在VMware Workstation上安装OpenWrt(软路由是啥?OpenWrt又是啥?长啥样?在VMware装一个瞅瞅),也介绍了如何…

LRUCache原理及源码实现

目录 LRUCache简介: LRUCache的实现: LinkedHashMap方法实现: 自己实现链表: 前言: 有需要本文章源码的友友请前往:LRUCache源码 LRUCache简介: LRU是Least Recently Used的缩写&#xf…

扣子Coze插件教程:如何使用Coze IDE创建插件

🧙‍♂️ 诸位好,吾乃斜杠君,编程界之翘楚,代码之大师。算法如流水,逻辑如棋局。 📜 吾之笔记,内含诸般技术之秘诀。吾欲以此笔记,传授编程之道,助汝解技术难题。 &#…

通过一篇文章让你了解Linux的重要性

Linux 前言一、什么是Linux后台vs前台为何大多数公司选择使用Linux作为后台服务器 二、Linux的背景介绍UNIX发展的历史Linux发展历史开源官网发行版本DebianUbuntu红帽企业级LinuxCentOSFedoraKali Linux 三、国内企业后台和用户使用Linux现状IT服务器Linux系统应用领域嵌入式L…

每日OJ题_01背包④_力扣1049. 最后一块石头的重量 II

目录 力扣1049. 最后一块石头的重量 II 问题解析 解析代码 滚动数组优化代码 力扣1049. 最后一块石头的重量 II 1049. 最后一块石头的重量 II 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意…

挑战全网,看谁能用栈和队列解决更多问题

1.栈 2.队列 3.栈和队列面试题 正文开始: 1. 栈 1.1 栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。 栈中的数据元素遵守 后…

项目之旅(前两周)

文章目录 学习总结input1.text 文本框2.password 密码框3.button 按钮4.file 文件还可定义上传类型 5.日期6.radio 单选框7. checkbox 复选框 项目总结生活总结 学习总结 input 本次写项目时才发现,input有很多种用法,这里列举几种 1.text 文本框 不…

嵌入式音视频进阶学习(建议收藏!)

前言: 大家好,今天花点时间,整理一下最近看的一些音视频英文文档资料和相关的一些音视频书籍,下面分享的资料,仅是个人的一个学习,仅供参考! rtp学习: 在这里给大家汇总的资料&#…

如何在Linux部署MeterSphere并实现公网访问进行远程测试工作

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…

LlamaIndex 文档1

文章目录 关于 LlamaIndex🚀 为什么要进行上下文增强?🦙 为什么使用 LlamaIndex 进行上下文增强?👨‍👩‍👧‍👦 LlamaIndex 适合谁? 入门🗺️生态系统社区相…

C++引用和右值引用

我最近开了几个专栏,诚信互三! > |||《算法专栏》::刷题教程来自网站《代码随想录》。||| > |||《C专栏》::记录我学习C的经历,看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

计算机网络 Cisco静态路由实验

一、实验要求与内容 1、路由器的基本配置 (1)命名 (2)关闭域名解析 (3)设置路由接口IP地址 2、配置静态路由以实现所有客户机都能互相通信 3、配置默认路由 4、了解ping命令和trace(跟踪…