JVM成神之路

目录

JVM入门关:

一:JVM的内存布局是咋样的?

二:方法区,永久代,元空间有什么区别?

三:常量池和字符串常量池有什么区别?

四:什么是堆溢出,什么情况下会造成堆溢出

五:什么是栈溢出,什么情况下会造成栈溢出 

JVM进阶关:

六:Java是编译型语言还是解释性语言,什么是JIT,什么是热点代码?

七:对象的生命周期包含哪些?

八:什么是双亲委派模型

九:Java有哪些场景是打破了双亲委派机制的

1.SPI机制

2.Tomcat

 十:Java有哪些引用类型

JVM成神关:

十一:如何判断一个对象是否存活

十二:常见的垃圾回收算法有哪些? 

十三:JVM常见的垃圾回收器有哪些? 

十四:CMS垃圾回收器有什么特点

十五:CMS垃圾回收期的执行流程是怎么样的呢?


JVM是Java跨平台实现的基础,也是每个Java开发程序员必备的技能之一,因为在后期的JVM调优方面,好的调优结果可以直接影响项目的执行效率,因此本篇文章就会带大家搞懂JVM的常见问题。

首先,当一个基础的问题,JVM是如何运行的,具体的运行流程可以观看我下面画的一张图

基于以上的图片可以得知,JVM执行的流程可以分为下面几步:

1.编译器首先会把 .java 源代码编译为 .class 文件,然年通过类加载器将 .class 文件加载到 运行时数据区域。

2.因为 .class 文件是JVM能识别的一套指令集,操作系统并不认识,因此需要执行引擎来将 .class 文件 进行解释为操作系统可以识别的指令。

3.在执行引擎解释.class文件时,会调用本地方法库的方法来辅助执行。

所以啊,JVM是通过:类加载器,执行引擎,本地方法库,运行时数据区四个模块来执行Java程序的。

明白了JVM是如何运行的,那我们就正式进入JVM的探索之旅啦!!!(搬好小板凳坐好了,准备出发了.....)

JVM入门关:

一:JVM的内存布局是咋样的?

通常所说的内存布局是指运行时数据区,要与Java内存模型分清楚(JMM),运行时数据区是指:堆,虚拟机栈,本地方法栈,方法区,程序计数器五个规范,这是在JVM虚拟机规范所提出来的。

:线程共享的,是JVM中最大的一块区域,存放的是对象的实例

虚拟机栈:线程私有的,存放是方法调用和局部变量(局部变量表,动态链接,操作数栈,方法出口)

本地方法栈:线程私有的,与虚拟机栈类似,存放的是本地方法(c++)

程序计数器:线程私有的,存放的是当前程序进行到了哪一步(当前指令的内存地址)

方法区:线程共享的,存放的是类的结构信息和静态成员变量,常量池等信息。

那什么是Java虚拟机规范呢?

Java虚拟机规范是指各个虚拟机的实现要遵守的一套规则,而Java虚拟机则是规范的具体实现,不同的操作系统都有自己的Java虚拟机实现,因此Java程序在可以一次编写处处可用。

二:方法区,永久代,元空间有什么区别?

方法区是Java虚拟机规范提出的一个专业名词规范,意味着所有的虚拟机实现都会执行该规范,而永久代是Jdk1.7之前的方法区的称呼(默认是使用的HotSpot虚拟机),在1.8之后,用元空间取代了永久代。

为什么要取消永久代呢?

是因为永久代的空间管理很难在满足需求,会出现OOM的问题,因此用元空间取代了永久代,永久代的改动如下:

1.空间大小可以动态调整,这时用的内存空间使用的是本地内存,而不是堆上的内存。

2.字符串常量池从永久代移动到了堆中,减少了方法区GC的压力。

三:常量池和字符串常量池有什么区别?

常量池和字符串常量池都是运行时数据区的一部分,但是二者有以下区别:

1.在jdk1.7之后,将字符串常量池从永久代移动到了堆中,而常量池是存放在元空间中的本地内存中。

2.常量池拥有更多的方法,可以存放字符常量,类,方法,字段的常量,而字符串常量池只可以存放字符串的常量

字符串常量池如下:

四:什么是堆溢出,什么情况下会造成堆溢出

堆溢出是指内存中有大量的垃圾对象无法回收,从而造成堆的内存溢出

常见的堆溢出有以下几种情况:

1.内存泄露:例如使用ThreadLocal时,没有主动释放就会导致内存泄漏。

2.无限创建大量对象

3.没有合理设置堆得大小

4.大量的Execl的导入和导出

五:什么是栈溢出,什么情况下会造成栈溢出 

栈溢出通常是指虚拟机栈溢出,而导致虚拟机栈溢出的主要原因是死循环和无限创建大的对象。

例如以下代码,就是一个典型的栈溢出现象,在 main 方法中循环调用 main 方法,循环产生的大量形参都会在栈空间进行创建,当超过栈空间的大小,就会导致栈空间溢出,发生 OOM。

public class StackOverflowErrorDemo {public static void main(String[] args) {main(args);   // Exception in thread "main" java.lang.StackOverflowError}
}

JVM进阶关:

恭喜你,小伙伴已经走到了JVM的进阶关卡了,下面我们就继续向JVM进发吧!!!

六:Java是编译型语言还是解释性语言,什么是JIT,什么是热点代码?

小伙伴是不是刚看到这个还有点懵,这什么东西,还是连着三个???小伙伴不要着急,我们慢慢来分析解决。

首先

解释型语言:不需要事先编译成机器码,而是在程序运行时将源代码逐行解释执行,例如JS语言就是典型的解释型语言
优点:跨平台性能好,无需编译
缺点:执行效率低

编译型语言:在程序执行前将源代码编译成机器可识别的机器码,然后执行,只需要编译一次,生成的可执行文件可重复运行。
优点:执行效率高
缺点:跨平台能力有限

而Java语言是属于二者之间的,也叫编译-解释型语言

编译阶段: .Java源文件经过编译器编译为 .calss 文件(字节码文件与平台无关,可以在任何系统的虚拟机上执行)

解释阶段:当程序执行时,java虚拟机会加载字节码,并对字节码进行解释执行(JIT:即时编译),JIT会对频繁执行的字节码编译成机器指令用来提高性能。

那热点代码又是啥?其实很简单,在不同的Jdk版本中,对于热点代码的定义是有所不同的,在 JDK 21 Client模式下为1500次,而在JDK 21 Server 模式下为10000次

热点代码的识别基于两种策略:方法调用次数和回边计数。

七:对象的生命周期包含哪些?

对象的生命中周期大致可以分为以下几个阶段

1.加载:根据类的全限定名将其转换为此类的二进制字节流,然后将此二进制流加载到运行时数据区中的方法区,在内存中生成一个这个类的对象,作为类的数据访问入口

2.链接

    2.1:验证:验证阶段主要是验证此类中的数据是否合法,例如验证文件格式,字节码,符号的引用等

    2.2:准备:为类中定义的静态变量分配内存并设置类的初始值,此时并不会真正赋值,而是赋默认值

    2.3:解析:将常量池中的符号引用转换为直接引用的过程,也就是初始化常量。

3.初始化:此时Java虚拟机才开始真正执行类的业务代码,将主导权交给主程序

4.使用:在程序中使用该类

5.销毁:此类的实例没有引用时就会根据垃圾回收算法回收此类的实例。

八:什么是双亲委派模型

所谓的双亲委派模型是指:当一个类加载器收到了类加载的请求,首先类不会自己加载而是将请求委派给父类的加载器,每一次都是如此,最终这个类的加载请求会到达顶级类的类加载器即启动类加载器(BootStrap ClassLoader),当父类无法加载该请求时,子类才会尝试自己记载该请求

使用双亲委派模型的好处:

1.避免类的重复记载

2.更加安全

九:Java有哪些场景是打破了双亲委派机制的

1.SPI机制

SPI机制就是“服务提供发现”机制,例如数据库的驱动就是典型SPI机制,用户调用JDBC接口,而各个数据库厂商都会实现JDBC的驱动,因此是从上往下来实现的

2.Tomcat

一个外置的Tomcat要部署多个应用,多个web应用程序在一个Tomcat容器类运行,而不会造成相互干扰和类冲突,因此Tomcat也打破了双亲委派机制 

 十:Java有哪些引用类型

 在jdk1.2以后Java官方提出了四种引用类型,分别为:强引用,软引用,弱引用,虚引用四种

强引用:一般来说,强引用是最常见的,使用Object object = new Object();都是强引用,除非是显示调用System.gc(),一般垃圾回收器不会主动去回收强引用的对象。类似于公司员工的核心员工一样

软引用:软引用是指一些还有用但不是必须回收的对象,类似于公司员工的好员工。只有在内存实在不够用的时候才会去垃圾回收

弱引用:弱引用是指不管内存是否够用,在下一次GC的时候一定会进行垃圾回收的对象,在Java中典型的运用的就是ThreadLocal中value的引用类型就是弱引用,因此为了防止内存泄露,需要爱使用完ThreadLocal后手动调用remove()方法释放内存,类似于公司员工的一般员工一样。

虚引用:在Java中虚引用又称为幻想引用,不能使用虚引用指向的对象,类似于不合格员工。 

JVM成神关:

恭喜小伙伴一路过五关斩六将来到了最后的一部分,JVM成神之路.......

十一:如何判断一个对象是否存活

在Java中利用引用计数法和可达性分析算法来判断一个对象是否存活。

引用计数法:给对象增加一个引用计数器,每当有对象引用时计数器+1,当引用失效时计数器-1,当计数器指向0时,表示该对象已经死亡
优点:实现简单,效率高
缺点:无法解决对象之间的循环引用问题

可达性分析:是指通过一个“GC Roots”的根节点开始逐步向下探索,走过的路径称为引用链,当引用链没有与之直接相连的话,就判断该对象是不可存活的。

那么通常又有哪些对象可以成为GC Roots呢?

1.虚拟机栈中引用的对象

2.本地方法栈中引用的对象

3.方法区中静态变量的引用对象

4.方法区中常量的引用对象

十二:常见的垃圾回收算法有哪些? 

在Java中常见的垃圾回收算法有:标记-清除算法,标记-整理算法,复制算法,分代算法等

标记-清除算法:是Java垃圾回收算法中最常见的一种垃圾回收算法,它的核心思想是统一标记可回收的对象,然后统一进行垃圾回收
优点:执行效率比较高,实现简单
缺点:使用标记-清除算法会出现大量的垃圾碎片,如果需要一大片连续的内存空间时候,此种垃圾回收的效率就会打折扣。

 标记-整理算法:标记-整理算法其实是标记-清除算法的一种升级,在统一标记后并不会立即执行垃圾回收,而是将存活的对象移动到另一端,然后清理端外的垃圾对象。
优点:不会存在垃圾碎片的问题
缺点:执行效率比较低下,因为在标记后还需要进行整理存活对象到另一端

复制算法:复制算法是标记-整理算法的一种升级,它的目的就是解决标记-整理算法的效率问题,它将可用内存区域按容量划分为两块大小相等的区域,然后在一块区域进行使用,当需要垃圾回收的时候,会将使用区域的存活对象复制到另一块未使用的区域,然后统一清除使用区域的垃圾对象
优点:执行效率高,不会存在垃圾碎片
缺点:内存空间的利用率比较低 

分代算法:分代算法就是将堆内存区域划分为新生代,老生代,然后在各自的区域进行垃圾回收的一种算法

分代算法的大致流程如下:

将堆内存区域划分为新生代,老生代,新生代占比1/3,老生代占比2/3,然后新生代区域又细分为3个区域:end区,To Survivor ,From Survivor占比分别为8:1:1
执行流程大致如下:
1.end区+from Survivor区存活的对象放入 To Survivor区

2.清空end区,from Survivor区

3.交换from Survivor区,To Survivor区

每交换一次存活的对象的年龄+1,当对象的年龄到达15时(HostPot默认是15),就会将该对象放进老生代,当老生代的区域不够用时,就会触发Full GC(全局垃圾回收)。

十三:JVM常见的垃圾回收器有哪些? 

常见的垃圾回收器下图所示:在新生代的Serial,ParNew,parallel Scavenge
在老生代的Serial Old,CMS,Parallel Old
已经后续一直在沿用的默认的垃圾回收器G1

在新生代的垃圾回收器常采用的垃圾回收算法是复制算法,在老生代采用的则是标记-整理算法

 

Serial,Serial Old是单线程环境下的串行执行的,不支持并发操作,意味着在进行垃圾回收时会阻塞用户线程,直到垃圾收集完成。

ParNew 相当于Serial的升级版本,唯一的区别就是ParNew 采用的并行回收,适用于多线程环境下

Parallel Scavenge,Parallel Old是专注于吞吐量的垃圾回收器
(吞吐量 = 用户线程执行时间/总时间 * 100%  = 用户线程执行时间/(GC时间+用户线程执行时间)* 100%)

CMS:专注于最短停顿时间的垃圾回收器

十四:CMS垃圾回收器有什么特点

CMS:并发标记清理回收器,是一种获取最短回收停顿时间为目标的垃圾收集器

CMS第一次初始标记,实现用户线程和垃圾回收线程同时执行
,采用的是标记-清除垃圾回收算法,也会存在STW(Stop the word,全局停顿),是一款老生代的垃圾回收器

优点:低延迟,并发收集
缺点:采用标记-清除算法会产生垃圾碎片

十五:CMS垃圾回收期的执行流程是怎么样的呢?

CMS的执行流程如图所示

1.初始标记:只标记GC Roots直接关联的对象,速度很快

2.并发标记:和用户线程同时会执行:GC Roots直接关联的对象继续向下探索,形成一条引用链

3.重新标记:对上一步“并发标记”阶段用户线程还在执行对象的变动进行修正标记

4.并发清除:使用并发-清除算法进行垃圾回收

好了,恭喜小伙伴,已经成功完成了JVM成神之路的所有关卡,与预祝小伙伴在未来的编程生涯中一路畅通,永无BUG!!!

(PS:本文一些图片配图来自于其他网络,若图片作者有看到请联系我删除)

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

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

相关文章

结构化系统分析,结构化系统设计(正片)

结构化分析方法:是面向数据流进行需求分析的方法,是用抽象模型的概念,按软件内部数据传递、变换的关系,自顶向下逐层分解,直到找到满足功能要求的所有可实现的软件为止。 数据流图(DFD)&#xf…

Linux系统:本机(物理主机)访问不了虚拟机中的apache服务问题的解决方案

学习目标: 提示:本文主要讲述-本机(物理主机)访问不了虚拟机中的apache服务情况下的解决方案 Linux系统:Ubuntu 23.04; 文中提到的“本机”:代表,宿主机,物理主机; 首先&#xff0c…

吴恩达深度学习笔记(7)

误差分析: 你运行一个算法代替人类计算,但是没有达到人类的效果,需要手动检查算法中的错误,对模型的一些部分做相应调整,才能更好地提升分类的精度。如果不加分析去做,可能几个月的努力对于提升精度并没有…

旋转花键材质及运用场景

旋转花键的材质有很多种,其材质选择是一个涉及多方面因素的重要决策,‌主要取决于应用场景的具体要求,包括设备的运行环境、负载大小、运行速度以及所需的耐磨性和耐腐蚀性等因素。 1、碳钢:价格低廉、具有较好的韧性和耐磨性&…

【分享】项目开发中的计算问题

事件背景 最近也就上个月吧,拿到一个新的需求,新建一个页面,三个Grid联动,涉及很多的页面和sql以及Java计算。 简略的画个表格表示一下: 第一个Grid: 第二个Grid: 第三个Grid: 业…

openKylin系统SSH服务配置结合cpolar轻松实现开放麒麟远程连接

前言 本文主要介绍如何在openKlyin系统中设置ssh连接,并结合cpolar内网穿透工具实现远程也可以ssh连接本地局域网内部署的openKlyin系统. openKylin是中国首个基于Linux 的桌面操作系统开发者平台,通过开放操作系统源代码的方式,打造具有自…

Axure显示与隐藏——元件动作一

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:显示与隐藏 主要内容:显示/隐藏/切换三种效果,动画效果,更多效果 应用场景:元件自身状态变化、操作…

LinkedList作者:我虽然开发了LinkedList,但是我更爱用ArrayList

感谢Java面试教程关于LinkedList经验分享 PS冷知识:LinkedList的作者更爱使用ArrayList。 ArrayList 和 LinkedList 是 Java 中两种常见的 List 实现类,它们在底层数据结构、性能特征和使用场景上有显著的区别。 底层数据结构: ArrayList …

Flux.never 使用说明书

public static <T> Flux<T> never()Create a Flux that will never signal any data, error or completion signal. 创建一个永远不会发出任何数据、错误或完成信号的 Flux。 Type Parameters: T - the Subscriber type target Returns: a never completing Flu…

软件缺陷报告

软件缺陷报告样例 软件缺陷基本内容 标题&#xff1a;一句话概述缺陷预置条件&#xff1a;缺陷的前提条件重现步骤&#xff1a;缺陷出现步骤期望结果&#xff1a;没有出现缺陷应该的结果实际结果&#xff1a;缺陷结果 软件缺陷的状态 新建&#xff08;激活&#xff09;->…

idea2024启动Java项目报Error running CloudPlApplication. Command line is too long.

idea2024启动Java项目报Error running CloudPlApplication. Command line is too long. 解决方案&#xff1a; 1、打开Edit Configurations 2、点击Modify options设置&#xff0c;勾选Shorten command line 3、在Edit Configurations界面下方新增的Shorten command line选项中…

前海一个很偏僻的路边免费停车点

​这个偏僻的路边免费停车点具体位置在前海金融中心大厦附近的中国中铁门口&#xff0c;大概有可以停30~50个位置的样子。缺点是很多灰尘哈。第一次路过的时候&#xff0c;我还以为很多车在等红绿灯&#xff0c;靠近才发现&#xff0c;这些车只是停在路面上。其中要想知道看车子…

MySQL | Explain的是使用详解

介绍 Explain是SQL分析工具中非常重要的一个功能&#xff0c;可以模拟优化器执行查询语句&#xff0c;帮助我们理解查询是如何执行的&#xff1b;分析查询执行计划可以帮助我们发现sql查询瓶颈&#xff0c;优化查询性能。 使用方法 MySQL5.7 版本之前使用&#xff1a; Expl…

解决 Elasticsearch cluster_block_exception 错误的终极指南

Elasticsearch 是一个功能强大的分布式搜索引擎&#xff0c;广泛应用于全文检索、实时分析等场景。 尽管如此&#xff0c;像任何复杂系统一样&#xff0c;它也会遇到一些运行问题&#xff0c;其中较为常见且影响较大的就是 cluster_block_exception 错误。 本文将深入解析这种错…

2024.10月16日- 关于Vue2(1)

一 VUE概述与环境搭建 1.1 Vue概述 1.1.1 简介 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款轻量级的用于构建用户界面的 渐进式的JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高…

入门!Linux 常见指令及权限管理全面指南

Linux 操作系统在现代计算机应用中扮演着重要的角色&#xff0c;广泛用于服务器、桌面系统、嵌入式设备及云计算平台等领域。理解和掌握 Linux 常见指令及权限管理机制&#xff0c;是每一位系统管理员和开发人员的基础技能。本文将详细介绍 Linux 系统的基本背景、常用指令、权…

桂林旅游一点通:SpringBoot平台应用

3系统分析 3.1可行性分析 通过对本桂林旅游景点导游平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本桂林旅游景点导游平台采用SSM框架&#xff0c;JAVA作…

iOS IPA上传到App Store Connect的三种方案详解

引言 在iOS应用开发中&#xff0c;完成开发后的重要一步就是将IPA文件上传到App Store Connect以便进行测试或发布到App Store。无论是使用Xcode进行原生开发&#xff0c;还是通过uni-app、Flutter等跨平台工具生成的IPA文件&#xff0c;上传到App Store的流程都是类似的。苹果…

package.json 里的 dependencies和devDependencies区别

dependencies&#xff08;依赖的意思&#xff09;&#xff1a; 通过 --save 安装&#xff0c;是需要发布到生产环境的。 比如项目中使用react&#xff0c;那么没有这个包的依赖就会报错&#xff0c;因此把依赖写入dependencies npm install <package-name>// 缩写 np…

Android Framwork从零上手(一)下载编译AOSP源码

Android Framwork从零上手&#xff08;一&#xff09;下载编译AOSP源码 什么是AOSP硬件要求虚拟机安装开发环境搭建下载编译源码下载 repo 工具初始化仓库并同步远程代码编译源码运行模拟器 Android 系统开发涉及的知识面很广&#xff0c;代码量大&#xff0c;复杂度高&#xf…