16道JVM面试题
1.jvm内存布局
1.程序计数器:当前线程正在执行的字节码的行号指示器,线程私有,唯一一个没有规定任何内存溢出错误的情况的区域。 2.Java虚拟机栈:线程私有,描述Java方法执行的内存模型,每个方法运行时都会创建一个栈帧,存放局部变量表、操作数栈、动态链接、方法出口等信息,每个方法的运行到结束对应一个栈帧的入栈和出栈。会有StackOverFlowError异常(申请的栈深度大于虚拟机所允许深度)和OutOfMemoryError异常(线程无法申请到足够内存)。 3.本地方法栈:功能与Java虚拟机栈相同,不过是为Native方法服务。 4.java堆:线程共享,存放实例对象和数组对象,申请空间不足抛出OutOfMemoryError异常。 5.方法区:线程共享,存储已被虚拟机加载的类的类信息、常量、静态变量、编译后的代码;运行时常量池存放class文件中描述的符号引用和直接引用,具有动态性。方法空间不足时抛出OutOfMemoryError异常。 6.直接内存:JVM规范之外的,NIO类引入了一种基于通道和缓冲区的I/O方式,可使用Native函数库直接分配内存,通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作,避免了在Java堆和Native堆中来回复制数据。
2.垃圾回收算法与垃圾回收器
垃圾收集算法: 1.标记-清除算法:将所有需要回收的对象先进行标记,标记结束后对标记的对象进行回收,效率低,会造成大量碎片。 2.复制算法:将内存分为两块大小相等的空间,每次只用其中一块,若一块内存用完了,就将这块内存中活着的对象复制到另一快内存中,将已使用的进行清除。不会产生碎片,但是会浪费一定的内存空间。堆的年轻代使用此算法,因为年轻代对象多为生存周期比较短的对象。年轻代将空间分为一个Eden和两个survivor,每次只使用Eden加一个survivor,回收时,将Eden和survivor中存活的对象复制到另一个survivor上,最后清理Eden和survivor。当Eden与survivor存活对象大于另一个survivor空间大小则需要老年代来担保。 3.标记-整理算法:标记阶段与标记-清除算法相同,标记完成后将所有存活对象向一端移动,然后清除掉端边界外对象。 4.分代收集算法:根据对象存活周期分为将内存分为新生代与老年代,新生代采取复制算法,老年代采用标记清除或标记整理算法。 垃圾回收器: 1.Serial收集器:单线程,垃圾回收时需要停下所有的线程工作。 2.ParNew收集器:Serial的多线程版本。 3.Parallel Scavenge收集器:年轻代,多线程并行收集。设计目标是实现一个可控的吞吐量(cpu运行代码时间/cpu消耗的总时间)。 4.Serial Old收集器:Serial老年代版本。 5.CMS:目标是获得最短回收停顿时间,基于标记清除算法,整个过程四个步骤:初始标记(标记GCRoot直接关联对象,速度很快)、并发标记(从GCRoot向下标记)、重新标记(并发标记过程中发生变化的对象)、并发清除(清除老年代垃圾)。初始标记和重新标记需要停顿所有用户线程。缺点:无法处理浮动垃圾、有空间碎片的产生、对CPU敏感。 6.G1收集器:唯一一个可同时用于老年代与新生代的收集器。采用标记整理算法,将堆分为不同大小星等的Region,G1追踪每个region的垃圾堆积的价值大小,然后有一个优先列表,优先回收价值最大的region,避免在整个堆中进行安全区域的垃圾收集,能建立可预测的停顿时间模型。整个过程四个步骤:初始标记、并发标记、最终标记(并发标记阶段发生变化的对象的变化记录写入线程remembered set log,同时与remembered set合并)、筛选回收(对每个region回收价值和成本拍寻,得到一个最好的回收方案并回收)。
3.垃圾回收对象时程序的逻辑是否可以继续执行
不同回收器不同:Serial、ParNew会暂停用户所有线程工作;CMS、G1会在某一阶段暂停用户线程。 4.内存分配策略 1.对象优先在Eden分配:若Eden无空间,Java虚拟机发起一次Minor GC。 2.大对象直接进入老年代:大对象指需要大量连续内存空间的对象(如长数组、长字符串) 3.长期存活的对象进入老年代:每个对象有一个对象年龄计数器,age=15晋升为老年代。age+1的两个情况:对象在Eden出生并经过一次Minor GC存活且被survivor容纳;在survivor区经历过一次minor GC。
4.空间分配担保
1.在Minor GC之前,先检查老年代最大可用连续空间是否大于新生代所有空间总和,成立则此次GC安全 2.不成立,查看是否允许担保失败设置为true,不允许则进行Full GC 3.允许,看老年代最大可用连续空间是否大于历次晋升到老年代对象的平均大小,不成立则Full GC 4.成立,则进行Minor GC
5.Java中的引用
1.强引用:new这类引用,只要强引用在,对象永远不会被回收。 2.软引用:描述有用但非必需的对象,在内存溢出之前,会把这些对象列入回收范围内进行第二次垃圾回收。 3.弱引用:描述非必需对象,只存活到下一次垃圾回收前。 4.虚引用:不会对生存时间造成影响,不能通过虚引用获得对象实例,只是在被虚引用的对象被回收时受到一个系统通知。
6.简述minor gc和full gc
Minor GC:从新生代回收内存,关键是Eden区内存不足,造成不足的原因是Java对象大部分是朝生夕死(java局部对象),而死掉的对象就需要在合适的时机被JVM回收 Major GC:从老年代回收内存,一般比Minor GC慢10倍以上。 Full GC:对整个堆来说的,出现Full GC通常伴随至少一次Minor GC,但非绝对。Full GC被触发的时候:老年代内存不足;持久代内存不足;统计得到的Minor GC晋升到老年代平均大小大于老年代空间。
7.java虚拟机new一个对象的创建过程
1.在常量池中查看是否有new的参数对应的类的符号引用,并检查这个符号引用对应的类是否被加载、解析、初始化 2.加载后,为新对象分配内存空间,对象多需要的内存大小在类被加载之后就被确定(堆内分配内存:指针碰撞、空闲列表)。 3.将分配的空间初始化为零值。 4.对对象头进行必要设置(实例是哪个类的实例、类的元信息数据、GC分代年龄等)。 5.执行方法,按照程序的值初始化。
8.java中的类加载机制
Java虚拟机中类加载过程:加载、验证、准备、解析、初始化。 1.加载:通过一个类的全限名来获取定义此类的二进制字节流;将这个字节流代表的静态存储结构转换为方法区的的动态存储结构;在内存中生成一个代表此类的java.lang.Class对象,作为方法区中这个类的访问入口。 2.验证:验证class文件中的字节流是否符合Java虚拟机规范,包括文件格式、元数据等。 3.准备:为类变量分配内存并设置类变量初始值,分配内存在方法区。 4.解析:将常量池中符号引用替换为直接引用的过程;符号引用与虚拟机实现的内存布局无关,是使用一组符号来描述所引用的目标。class文件中不会保存各个方法的最终布局信息,所以这些符号引用不经过转化是无法得到真正的内存入口地址;直接引用与虚拟机实现的内存布局有关,可以是直接指向目标的指针,偏移量或指向目标的句柄。此过程主要是静态链接,方法主要为静态方法和私有方法。 5.初始化:真正执行类中定义的Java代码。初始化执行类的方法,该方法由编译器自动收集类中所有类变量的赋值动作和静态语句块的语句合并产生,且保证子类的clinit调用之前会先执行父类的clinit方法,clinit可以不存在(如没有类变量和静态语句块)。
9.双亲委派模型
java中类加载器主要用于实现类的加载,Java中的类和类加载器一起唯一确定类在JVM中的一致性。 系统提供的类加载器:启动类加载器、扩展类加载器、应用程序类加载器。 1.启动类加载器:用C++实现,是JVM的一部分,其他加载器使用Java实现,独立于JVM。主要负责加载<JAVA_HOME>\lib目录下的类库或被-Xbootclasspath参数指定的路径中的类库,应用程序不能使用该类加载器。 2.扩展类加载器:负责加载<JAVA_HOME>/lib/ext目录下或者类系统变量java.ext.dirs指定路径下的类库,开发者课直接使用。 3.应用程序类加载器:主要负责加载classpath下的类库,若应用程序没有自定义类加载器,默认使用此加载器 双亲委派模型要求除了启动类加载器,其他类加载器都有自己的父类加载器,使用组合关系来实现复用父类加载器。过程:若一个类加载器收到类加载请求,会把此请求委派给父类加载器去完成,每层都是如此,因此所有的加载请求最后都会传到启动类加载器;只有当父类加载器反馈不能加载,才会把此请求交给子类完成。 好处:使得java类伴随他的类加载器有了优先级;保证Java程序运行的稳定性
10.简述分派
包括静态分派与动态分派 1.静态分派:发生在编译时期,所有依赖静态类型来定位方法执行版本的分派称为静态分派,典型应用为方法重载。 2.动态分派:在运行期根据实际类型确定方法执行版本的分派过程。典型应用为方法重写,实现是在方法去中建立方法表,若子类中没有重写父类方法,则子类虚方法表中该方法的入口地址与父类指向相同,否则子类方法表中地址会替换为指向子类重写的方法的入口地址。
11.对象的内存布局
对象内存布局分为三部分:对象头、实例数据、对齐填充。 对象头包含两部分: 1.存储对象自身运行时数据:哈希码、分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等 2.对象指向它的类元数据指针–类型指针 实例数据:程序代码中所定义的各种类型的字段内容 对齐填充:不是必然存在,仅起到占位符作用(对象大小必须是8子节整数倍)
12.虚拟机栈中的各个部分
1.局部变量表:存放方法参数和方法内部定义的局部变量,以变量槽Slot为基本单位,一个Slot可以存放32位以内的数据类型,可重用。 2.操作数栈:先入后出,32位数据类型所占栈容量为1,64为数据类型所占栈容量为2 3.动态链接:常量池中符号引用有一部分在每次运行期间转换为直接引用,这部分称为动态链接。(一部分在类加载阶段或第一次使用时转换为直接引用—静态解析) 4.方法返回地址:方法执行后退出的两种方式:正常完成出口(执行引擎遇到任意一个返回的字节码指令)和异常完成出口(在方法执行过程中遇到异常且此异常未被处理)。两种方式都需要返回到方法被调用的位置程序才能继续执行(正常退出时调用者的PC计数器的值可以作为返回地址且栈帧中很可能保存这个计数器值;异常退出返回地址要通过异常处理器表来确定,栈帧中一般不会保存)。
13.Java内存模型的happen before原则
如果两个操作存在happens-before关系,那么前一个操作的结果就会对后面一个操作可见,是定义的两个操作之间的偏序关系,常见的规则: 1.程序顺序规则:一个线程中每个操作,happens-before于该线程中的任意后续操作 2.监视器锁规则:对一个锁的解锁,happens-before于随后这个锁的加锁 3.volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个域的读 4.传递性:若A happens-before B,B happens-before C,则A happens-before C 5.start()规则:如果线程A执行ThreadB.start(),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作。 6.join()规则:若线程A 执行ThreadB.join()并成功返回,则线程B的任意操作happens-before于线程A从ThreadB.jion()操作返回成功。
14.java中方法区存放哪些东西?jvm如何控制方法区的大小以及内存溢出的原因和解决
方法区大小不是固定的,jvm可根据需要动态调整。方法区主要存放类信息、常量、静态变量、编译后的代码。 控制方法区大小:减少程序中class数量、尽量使用较少的静态变量 修改:-XX:MaxPerSize调大 StackOverflowError异常:线程的方法嵌套调用层次太多,随着Java栈中桢的增多,最终会由于该线程Java栈中所有栈帧总和大于-Xss设置的值而产生此异常。
15.jvm OutMemory的种类
1.堆溢出:被缓存的实例对象,大的map,list引用大的对象等 2.栈溢出:栈帧太多 3.方法区溢出:加载很多类会有可能出现,GC不会在主程序运行期对此区域进行清理,可通过设置jvm启动参数解决:-XX:MaxPermSize=256m
16.jvm如何判断对象是否失效?可达性分析是否可以解决循环引用
1.引用计数器算法:给对象添加一个引用计数器,当被引用时给计数器加1,引用失效减1,当为0时对象失效。实现简单,判定效率高,无法解决循环引用问题。 2.可达性分析算法:将一系列GC Root作为起始点,从这些节点开始向下搜索,所走过路径称为引用链,若一个对象无引用链,则判断是否执行finalize()方法,若finalize()被覆盖并且没被JVM调用过,则执行此方法,执行后若还无引用链,则对象失效。 可以作为GC Root的对象:
- 虚拟机栈中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中Native方法引用的对象
相关文章:
16道JVM面试题
1.jvm内存布局 1.程序计数器:当前线程正在执行的字节码的行号指示器,线程私有,唯一一个没有规定任何内存溢出错误的情况的区域。 2.Java虚拟机栈:线程私有,描述Java方法执行的内存模型,每个方法运行时都会…...
HttpRunner 接口自动化测试框架实战,打造高效测试流程
简介 2018年python开发者大会上,了解到HttpRuuner开源自动化测试框架,采用YAML/JSON格式管理用例,能录制和转换生成用例功能,充分做到用例与测试代码分离,相比excel维护测试场景数据更加简洁。在此,利用业…...
手写一个webpack插件(plugin)
熟悉 vue 和 react 的小伙伴们都知道,在执行过程中会有各种生命周期钩子,其实webpack也不例外,在使用webpack的时候,我们有时候需要在 webpack 构建流程中引入自定义的行为,这个时候就可以在 hooks 钩子中添加自己的方…...
jvm常见面试题
0x01. 内存模型以及分区,需要详细到每个区放什么。 栈区: 栈分为java虚拟机栈和本地方法栈 重点是Java虚拟机栈,它是线程私有的,生命周期与线程相同。 每个方法执行都会创建一个栈帧,用于存放局部变量表࿰…...
TF-A 项目的长期支持介绍
引流关键词:Armv8-A, Armv9-A, Cortex-A, Cortex-A12, Cortex-A15, Cortex-A17, Cortex-A32, Cortex-A34, Cortex-A35, Cortex-A5, Cortex-A510, Cortex-A53, Cortex-A55, Cortex-A57, Cortex-A65, Cortex-A65AE, Cortex-A7, Cortex-A710, Cortex-A715, Cortex-A72, Cortex-A7…...
企业电子招标采购系统源码java 版本 Spring Cloud + Spring Boot
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…...
7.Mysql 事务底层
一、事务的基础知识 mysql中的事务 分为 显式事务 和 隐式事务。 1.1 显式事务 显式事务就是我们手动开启事务,并且提交事务比如: -- 开启事务 begin; -- 执行查询语句 select *from where id = 1 for update ; -- 提交事务 commit;1.2 隐式事务 在 MySQL 中,隐式事务是…...
15.DIY可视化-拖拽设计1天搞定主流小程序-分类联动文章列表实时刷新
分类联动文章列表实时刷新 本教程均在第一节中项目启动下操作 分类联动文章列表实时刷新前言需求一:功能实现:点击首页分类,对应分类内容显示到当前页一、清空原分类界面:二. 设置选项卡三:设定展示内容字段:1.跨页面复制:文章分类组件到分类
CRect rect; this->GetClientRect(rect); pDC->Ellipse(rect); // DDALineView.cpp : implementation of the CDDALineView class // #include “stdafx.h” #include “DDALine.h” #include “DDALineDoc.h” #include “DDALineView.h” #ifdef _DEBUG #define new…...
Spark大数据处理学习笔记(3.2.1)掌握RDD算子
该文章主要为完成实训任务,详细实现过程及结果见【http://t.csdn.cn/FArNP】 文章目录 一、准备工作1.1 准备文件1. 准备本地系统文件2. 把文件上传到 1.2 启动Spark Shell1. 启动HDFS服务2. 启动Spark服务3. 启动Spark Shell 二、掌握转换算子2.1 映射算子 - map()…...
lammps初级:石墨烯、金属材料、纳米流体、热传导、多成分体系、金属、半导体材料的辐照、自建分子力场、MOFS、H2/CO2混合气体等模拟
1 LAMMPS的基础入门——初识LAMMPS是什么?能干什么?怎么用? 1.1 LAMMPS在win10和ubuntu系统的安装及使用 1.2 in文件结构格式 1.3 in文件基本语法:结合实例,讲解in文件常用命令 1.4 data文件格式 1.5 LAMMPS常见错误解…...
【MarkerDown】CSDN Markdown之时序图sequenceDiagram详解
CSDN Markdown之时序图sequenceDiagram详解 序列图 sequenceDiagram参与者与组参与者 participant拟人符号 actor别名 as组 box 消息(连线)激活/失活 activate/deactivate备注 Note循环 loop备选 Alt并行 par临界区 critical中断 break背景高亮 rect注释 %%转义字符的实体代码序…...
ReentrantLock实现原理-公平锁
在ReentrantLock实现原理(1)一节中,我们了解了ReentrantLock非公平锁的获取流程,在本节中我们来看下ReentrantLock公平锁的创建以及锁管理流程 创建ReentrantLock公平锁 创建公平锁代码如下: ReentrantLock reentrantLock new ReentrantL…...
掌握Scala数据结构(2)MAP、TUPLE、SET
一、映射 (Map) (一)不可变映射 1、创建不可变映射 创建不可变映射mp,用键->值的形式 创建不可变映射mp,用(键, 值)的形式 注意:Map是特质(Scala里的trait,相当于Java里的interface&#…...
flutter:文件系统目录、文件读写
参考 参考:老孟 文件存储和网络请求 数据存储 Dart的 IO 库包含了文件读写的相关类,它属于 Dart 语法标准的一部分,所以通过 Dart IO 库,无论是 Dart VM 下的脚本还是 Flutter,都是通过 Dart IO 库来操作文件的。但…...
计算机提示“找不到vcruntime140.dll,无法继续执行代码可”以这样子修复
首先,对于那些不熟悉的人来说,vcruntime140.dll是一个关键文件,用于在Windows操作系统上运行使用C语言编写的大型应用程序。如果你正在运行或安装这样的应用程序,但找不到vcruntime140.dll文件,那么你的应用程序可能无…...
深度学习pytorch实战五:基于ResNet34迁移学习的方法图像分类篇自建花数据集图像分类(5类)超详细代码
1.数据集简介 2.模型相关知识 3.split_data.py——训练集与测试集划分 4.model.py——定义ResNet34网络模型 5.train.py——加载数据集并训练,训练集计算损失值loss,测试集计算accuracy,保存训练好的网络参数 6.predict.py——利用训练好的网…...
Rust in Action笔记 第五章 深入理解数据
如果希望看到f32类型的数转换成整型数字u32类型,需要在unsafe包裹下调用std::mem::transmute(data),因为在安全的Rust语法中没有把整型数据按照bit转换成浮点数据的实现,如果想要看到浮点数的二进制输出(通过{:b})&…...
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码 最近在学习Cocos Creator,作为新手,刚刚开始学习Cocos Creator,刚刚入门,这里记录一下飞机大战小游戏实现。 https://wxaurl.cn/VEgRy2eTMyi 一 安装CocosDashBo…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...
