JVM的几个面试重点

news2024/12/19 20:36:59

JVM的内存区域划分

JVM类加载机制

        前言

        Java程序最开始是一个 .java 的文件,JVM把它编译成  .closs 文件(字节码文件),运行 Java 程序, JVM 就会读取 .class 文件,把文件内容读取到内存中,构造出一个 .class 对象(类对象)

        1.加载

        JVM 加载 .class 文件的时候需要用到 “类加载器模块” ,JVM 中自带了三个类加载器模块

        分别是,Bootstrap ClassLoader(负责加载标准库中的类)

                        Extension ClassLoader(负责加载 JVM 扩展的库)

                        Application ClassLoader(负责加载第三方库)

        三个类加载器的优先级由高到低

        要加载 .class 文件,我们就需要先找到 .class 文件,此时我们就涉及到双亲委派模型

        什么是双亲委派模型

        如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载。

        假设我们现在需要加载一个 .class 文件,此时类加载的请求就会传给 Application ClassLoader (负责加载第三方库),但 Application ClassLoader 不会直接就尝试寻找并加载 .class 文件,而是把这个请求发送给自己的父类 Extension ClassLoader(负责加载 JVM 扩展的库),同理 Extension ClassLoader 也会把类加载的请求传给 Bootstrap ClassLoader(负责加载标准库中的类) , Bootstrap ClassLoader 没有父类了,才会真正的去搜索  .class 文件,并加载到内存中,如果 Bootstrap ClassLoader 没有查找到  .class 文件,就将类加载的请求传回给子类  Extension ClassLoader 进行加载,同理,要是  Extension ClassLoader 没有查找到  .class 文件,也会将类加载的请求传回给子类 Application ClassLoader 进行加载,经过这段流程的寻找,一般就能找到对应的  .class 文件

        2.验证

        找到  .class 文件以后还需要验证  .class 文件的格式是否符合约束要求

        3.准备

        准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值 的阶段。

        4.解析

        解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程。

        5.初始化

        初始化阶段,Java 虚拟机真正开始执行类中编写的 Java 程序代码,将主导权移交给应用程序。初始化 阶段就是执行类构造器方法的过程。

        类在什么时候被加载

        懒汉模式,用到了才加载

        1.构造类的实例

        2.使用了类的静态方法,静态属性

        3.子类的加载会触发父类

        类加载了以后,后面就不必再次加载了

JVM垃圾回收机制

        很多编程语言都有垃圾回收的机制,Java也不例外,垃圾回收机制可以自动的将不再使用的对象进行销毁,释放对象所占用的内存空间

        在 JVM 的内存区域划分中,我们进行垃圾回收的主要位置是堆,因为栈和计数器是和线程共存亡的,当线程结束以后便会自动释放栈和计数器所占的内存,而我们实例化的对象都是放到堆中的

        进行垃圾回收,首先我们需要考虑哪些对象是死亡对象(垃圾),当一个对象没有被引用指向的时候,我们就可以认为这个对象是死亡对象,因为这个对象用户已经无法访问到它了

死亡对象的判断算法

        1.引用计数算法

        引用计数描述的算法为: 给对象增加一个引用计数器,每当有一个地方引用它时,计数器就+1;当引用失效时,计数器就-1;任 何时刻计数器为0的对象就是不能再被使用的,即对象已"死"。 引用计数法实现简单,判定效率也比较高,在大部分情况下都是一个不错的算法。比如Python语言就采 用引用计数法进行内存管理。 但是,在主流的JVM中没有选用引用计数法来管理内存,最主要的原因就是引用计数法无法解决对象的 循环引用问题

        

        2.可达性分析(Java中实际采取的方案)

        JVM 首先会遍历代码中所有的引用,根据引用找到对应的对象,将能通过引用访问到的对象标记成可达,完成整个遍历以后,没有被标记成可达的对象,也就是不可达,就相当于是垃圾了

        

        在分析完哪些对象是垃圾对象以后,我们就需要将这些垃圾对象进行回收,回收有以下的几种算法

垃圾回收

        1.直接释放

        直接释放对象,很简单干脆,但是存在内存碎片问题

        因为在申请内存的时候,都是申请的连续的内存空间,直接释放内存的话就会破坏原有的连续性,产生内存碎片,随着程序运行得越来越多,内存碎片也会越来越多,越来越碎,这样就会出现明明有内存但是无法申请的情况,这是一个很严重的问题

        2.复制算法

        把一个内存分两份,用一份丢一份(用双倍的空间来存储对象),存储对象的时候用两倍的空间存储,一开始将对象统一存放在左边的空间,当要进行垃圾回收的时候,就将不需要回收的对象复制到右边,然后再将左边的内存全部释放,下一次进行垃圾回收就将复制到左边,把右边的内存全部释放,这样就能解决内存碎片问题

        但是,该算法会浪费一半的空间,而且要频繁进行对象的复制,会大大影响效率

        3.分代算法(GC)(当前JVM采用)

        当前 JVM 垃圾收集都采用的是"分代收集(Generational Collection)"算法,这个算法并没有新思想,只 是根据对象存活周期的不同将内存划分为几块。一般是把Java堆分为新生代和老年代。在新生代中,每 次垃圾回收都有大批对象死去,只有少量存活,因此我们采用复制算法;而老年代中对象存活率高、没 有额外空间对它进行分配担保,就必须采用"标记-清理"或者"标记-整理"算法。

        将整个堆分为三个部分:1.新生代,2.幸存区,3.老年代

       JVM 会周期性的遍历三个部分中的对象

        一开始创建的对象放到新生代,遍历新生代中的对象,将垃圾对象进行释放(大多数的对象活不过第一轮GC遍历),不是垃圾对象的就复制到幸存区中

        幸存区分为两个部分,采用的是复制算法,在幸存区经过多轮GC遍历还没有成为垃圾对象被回收的对象就会被复制到老年代,老年代中的对象是不容易被回收的对象,所以进行GC遍历的频率也较低

        

        

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

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

相关文章

C++:为什么析构函数一般写为虚函数

如果没有继承关系,析构函数写不写为虚函数都可以。 如果有继承关系、有多态性的使用需求时,就需要把析构函数写为虚函数,这样可以避免潜在的内存泄漏问题。 比如:当一个类被设计为作为基类,并且通过基类指针或引用dele…

【网络爬虫 | Python】数字货币ok链上bitcoin大额交易实时爬取,存入 mysql 数据库

文章目录 一、网站分析二、js 逆向获取 X-Apikey三、python 调用 js 获取 X-Apikey四、python 爬虫部分五、mysql 数据库、日志、配置文件、目录结构六、结尾 一、网站分析 oklink:https://www.oklink.com/ btc 大额交易:https://www.oklink.com/btc/tx-…

Fiddler抓包VSCode和探索

前言: 最近在使用 VSCode 调试 web 程序时,遇到一些问题,当时不知道如何是好。所以决定抓看来看一看,然后一顿操作猛如虎,成功安装了抓包软件 – Fiddler Classic。我并没有使用 Postman 这种重量级的 HTTP 测试软件&a…

windows系统kettle9.3一键安装启动

程序下载、解压 通过百度网盘下载,直接解压即可 解压之后 双击运行 程序路径 pdi-ce-9.3.0.0-428一键安装启动\pdi-ce-9.3.0.0-428\data-integration

【FA-BP预测】基于萤火虫算法优化BP神经网络回归预测研究(Matlab代码实现)

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

Linux中常见的权限问题

目录 前言1. 目录权限2. umask3. 粘滞位结语 前言 在了解完上一篇文章 Linux权限的理解与操作 之后,还有一些比较常见的权限问题需要我们去了解。其中包括目录的权限,umask 以及 粘滞位的使用。 1. 目录权限 问题一:进入一个目录&#xff0…

STM32F4_FATFS

目录 前言 1. 文件系统简介 2. FATFS文件系统 2.1 实际演练 2.2 FATFS读书笔记整理 2.3 FAT文件系统的神秘面纱 2.3.1 引导扇区 2.3.2 引导代码 2.3.3 FSINF0信息扇区 2.3.4 FAT表 2.3.5 FAT32数据区 2.3.6 子目录 2.3.7 目录项 3. 实验程序 3.1 main.c 3.2 di…

美团面试:Oracle JDK那么好,为何要用Open JDK?

说在前面 在40岁老架构师 尼恩的读者交流群(50)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: 既然 Oracle JDK 这么好,那为什么还要有 OpenJDK&…

YZ系列工具之YZ12:VBA_4种方法设计下拉列表

我给VBA下的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套一部VBA手册,教程分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的…

OJ第五篇

文章目录 用队列实现栈用栈实现队列设计循环队列 用队列实现栈 链接:用队列实现栈 这道题是让我们用两个队列实现一个栈,简单来说,就是利用队列来实现一个先入后出的功能,我们知道队列是先入先出,如何用两个队列来实…

Vue2基础知识(四) 自定义指令

目录 一 自定义指令1.1 定义1.2 自定义局部指令1.3 全局注册指令1.4 钩子函数1.5 动态传参1.6 使用场景 💌 所属专栏:【Vue2】😀 作 者:长安不及十里💻工作:目前从事电力行业开发🌈目标&#xf…

全国342个城市往返最短通勤时间(铁路)数据

全国342个城市往返最短通勤时间(铁路)数据 1、时间:采集时间是2022年 2、来源:12306 3、数据说明:数据采集12306数据,整理全国342个城市往返最短通勤时间,本数据是铁路包含动车、高铁所有路线…

【GESP】2023年06月图形化三级 -- 计算最终值

文章目录 计算最终值【题目描述】【输入描述】【输出描述】【参考答案】其他测试用例 计算最终值 【题目描述】 默认小猫角色,白色背景。存在一种仅支持2种操作和1个变量的编程语言: X 使变量 “X” 的值增加1X-- 使变量 “X” 的值减少 1 最初&#…

基于SAE堆叠自编码器的单维时间序列预测研究(matlab代码实现)

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

在没有康托尔对角化方法的情况下证明实数的不可数性

乔治康托尔 |图片来源: 维基百科 一、说明 对于那些对数学感兴趣的人来说,无穷大实际上可以有不同的大小,这可能是一个众所周知的事实。事实上,最著名的例子是所有实数的集合比所有自然数的集合“大”。你可能知道,这实…

Docker部署SpringBoot +Vue项目流程详解(含域名 + HTTPS)

文章目录 前言1、选购服务器2、部署 Docker3、前端、后端项目打包4、配置 Dockerfile5、配置 Nginx6、配置 DockerCompose6、启动 DockerCompose 完成部署7、【可选】域名 SSL证书 前言 本次整体部署操作使用阿里云服务器,这里我选择的是香港地区的2核2G ECS&…

打击勒索病毒:防御.kat6.l6st6r勒索病毒的最佳策略

导言: 我们日常生活和工作的方方面面都离不开数字化,但这也意味着面临日益复杂的网络威胁。.kat6.l6st6r勒索病毒就是其中之一,如果你的计算机感染了这种恶意软件,你的数据可能会遭到加密并要求支付赎金才能解锁。在这篇终极指南…

STM32F4_音乐播放器

目录 前言 1. WAV简介 1.1 WAVE文件的内部结构 2. WM8978简介 3. I2S简介 4. 硬件设计 5. 实验程序 5.1 main.c 5.2 I2S.c 5.3 I2S.h 5.4 WM8978.c 5.5 WM8978.h 前言 STM32F4开发板拥有全双工I2S(也就是可以同时双向进行传输,A到B传输信息的…

强化学习问题(7)--- Python和Pytorch,Tensorflow的版本对应

1.问题 之前下载的python3.8,在对应Pytorch和Tensorflow时没太在意版本,在运行一些代码时,提示Pytorch和Tensorflow版本过高,直接降下来,有时候又和Python3.8不兼容,所以又在虚拟环境搞一个Pyhon3.7&#x…

Brachistochrone:使用变分法找到最快下降曲线

一、说明 对于任何对数学和科学感兴趣的人,您可能已经知道了急速线,因为它经常在各种流行的教学频道(例如 Vsauce 和 3Blue1Brown)上谈论。虽然有多种方法可以解决急速线问题,但在这篇文章中,本文将使用变分…