JVM的几个面试重点

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.mzph.cn/news/114426.shtml

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

相关文章

YOLOv5:修改backbone为SPD-Conv

YOLOv5:修改backbone为SPD-Conv 前言前提条件相关介绍SPD-ConvYOLOv5修改backbone为SPD-Conv修改common.py修改yolo.py修改yolov5.yaml配置 参考 前言 记录在YOLOv5修改backbone操作,方便自己查阅。由于本人水平有限,难免出现错漏&#xff0c…

HammerDB的安装和使用(超详细)

目录 ​编辑 一、HammerDB的介绍 二、HammerDB的安装 1、下载hammerdb安装包 2、权限配置以及安装 3、查看安装目录 三、安装前的配置 1、启动监听 2、启动数据库 3、创建表空间 1.修改临时表空间 2…

【源码解析】Spring源码解读-bean的加载

Spring的整体流程其实就是通过配置 xml、注解将自定义bean类信息进行配置,然后通过BeanDefinitionReader读取配置信息,由Dom转换成xml解析成Docment。在通过加载的配置信息进行初始化Bean对象,然后在对象的前后进行处理,也就是不同…

面向对象【构造器】

文章目录 构造器定义构造器的作用构造器的使用说明无参构造器带参数的构造器构造器的重载使用构造器创建对象 总结 构造器定义 构造器是一种特殊类型的方法,它与类同名,没有返回值,并且用于在创建对象时执行初始化操作。构造器的名称必须与类…

java蓝桥杯前10题总结

文章目录 1.单词分析1.代码2.知识点 2.成绩统计1.代码2.知识点1.如何四舍五入?2.如何保留小数点后几位小数呢? 3.最短路4.回文日期1.代码2.知识点1.日期类2.字符串细节3.连等的细节 5.门牌制作1.代码 6.卡片1.代码2.细节 7.数字三角形1.代码2.细节 8.成绩…

最强英文开源模型LLaMA架构探秘,从原理到源码

导读: LLaMA 65B是由Meta AI(原Facebook AI)发布并宣布开源的真正意义上的千亿级别大语言模型,发布之初(2023年2月24日)曾引起不小的轰动。LLaMA的横空出世,更像是模型大战中一个搅局者。虽然它…

AI篇-如何用AI辅助对图片进行鉴赏

前言 目录 前言 一、观众侧鉴赏图片 方法1:直接将图片发给文心一言,让文心一言分析。 方法2(正确方法):将图片简单介绍并把图片发给文心一言,让文心一言分析。 二、作者介绍图片 方法(正…

(一)docker:建立oracle数据库

前言,整个安装过程主要根据docker-images/OracleDatabase/SingleInstance /README.md ,里边对如何制作容器讲的比较清楚,唯一问题就是都是英文,可以使用谷歌浏览器自动翻译成中文,自己再对照英文相互参照来制作提前准备…

docker报错问题解决:Error Invalid or corrupt jarfile app.jar

文章目录 1.问题描述2.问题分析3.问题解决 1.问题描述 此时处在 /home/ubuntu/app 目录下,并且在该目录下有一个 jenkins-0.0.1-SNAPSHOT.jar。 我在 /home/ubuntu/app 目录下执行了 docker 容器运行命令: # 映射 8859 端口 # 容器名为 jenkins-demo #…

使用Dockerfile生成docker镜像和容器的方法记录

一、相关介绍 Docker 是一个开源的容器化平台,其中的主要概念是容器和镜像。 容器是 Docker 的运行实例。 它是一个独立并可执行的软件包,包含了应用程序及其依赖的所有组件(如代码、运行时环境、系统工具、库文件等)。容器可以在…

我的电子萝卜刀火了吗?

引言 大家好,我是亿元程序员,一位有着8年游戏行业经验的主程。 笔者在上一篇文章《萝卜刀真的太危险了,于是我用Cocos做了一个》中说到因女儿从学校回来之后想要我给她买一把萝卜刀被我拒绝,但是又想要让她体验一下,因此用Cocos…

REDIS命令

常见文件名 Redis-cli使用命令 1、启动Redis2、连接Redis3、停止Redis4、发送命令 1、redis-cli带参数运行,如:2、redis-cli不带参数运行,如:5、测试连通性key操作命令 获取所有键查询键是否存在删除键查询键类型移动键查询key的生…

零基础学python:错误与异常

嗨喽,大家好呀~这里是爱看美女的茜茜呐 语法错误 异常:大多数的异常都不会被程序处理,都以错误信息的形式展现在这里 👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~ pyth…

Ubuntu源码编译samba

概述 本人最近研究samba的源码,但是在源码编译的时候,本以为直接config,make,make install。没想到编译过程中碰到很多麻烦,主要是各种依赖问题。 基于此,本文把samba编译的详细过程记录下来,以供再次研究借鉴。 软件…

力扣刷题 day50:10-20

1.存在重复元素 给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。 方法一:集合去重 #方法一:集合去重 def containsDuplicate(nums):return len(n…

AWS SAA-C03考试知识点整理

S3: 不用于数据库功能 分类: S3 Standard :以便频繁访问 S3 Standard-IA 或 S3 One Zone-IA : 不经常访问的数据 Glacier: 最低的成本归档数据 S3 Intelligent-Tiering智能分层 :存储具有不断变化或未知访问…

KubeSphere一键安装部署K8S集群(单master节点)-亲测过

1. 基础环境优化 hostnamectl set-hostname master1 && bash hostnamectl set-hostname node1 && bash hostnamectl set-hostname node2 && bashcat >> /etc/hosts << EOF 192.168.0.34 master1 192.168.0.45 node1 192.168.0.209…

从零开始,学好 Python 从大一新生自我介绍开始

从零开始&#xff0c;学好 Python 从大一新生自我介绍开始 大家好&#xff0c;我叫xxx,今年18岁&#xff0c;刚刚入学不久。我决定从零开始系统学习Python编程语言。 Python是一种解释型、交互式和脚本编程语言。它由荷兰人Guido van Rossum在1991年左右创立&#xff0c;语法简…

Python学习第2天-安装pycharm

文章目录 前言一、下载二、安装1.选择安装目录2.安装配置 总结 前言 好用的工具可以极大地提高生产力&#xff0c;开发Python推荐使用jetbrains全家桶的pycharm。 一、下载 通过官网下载安装包。 二、安装 1.选择安装目录 2.安装配置 一路Next&#xff0c;安装完成 总结 …

机器学习(23)---Boosting tree(课堂笔记)

文章目录 一、知识记录二、题目2.1 题目12.2 题目22.3 题目三2.4 答案书写 一、知识记录 二、题目 2.1 题目1 2.2 题目2 2.3 题目三 T 4 T_4 T4​中 0.15 0.15 0.15 改为 − 0.16 -0.16 −0.16&#xff0c; − 0.22 -0.22 −0.22 改为 0.11 0.11 0.11。 2.4 答案书写