【JVM】面试题汇总

  • JVM
    • 1. 什么是JVM?
    • 2. 了解过字节码文件的组成吗?
    • 3. 什么是运行时数据区
    • 4. 哪些区域会出现内存溢出
    • 5. JVM在JDK6-8之间在内存区域上有什么不同
    • 6. 类的生命周期
    • 7. 什么是类加载器?类加载器有哪几种
    • 8. 什么是双亲委派机制?有什么好处
    • 9. 如何打破双亲委派机制
    • 10. 如何判断堆上的对象有没有被引用?
    • 11. JVM 中都有哪些引用类型?
    • 12. ThreadLocal中为什么要使用弱引用?
    • 13. 有哪些常见的垃圾回收算法?
    • 14. 分代GC算法为什么将堆分成新生代和老年代?
    • 15. 有哪些常用的垃圾回收器
    • 16. 内存泄漏的原因

JVM

1. 什么是JVM?

答:

  • JVM 是运行 Java字节码文件的虚拟机,它负责对象内存的分配、完成自动的垃圾回收。

  • JVM 是运行 Java字节码文件的虚拟机,字节码文件和不同系统实现的JVM是实现跨平台的关键。
  • JVM的功能有三项:
    • 第一是解释执行字节码指令;
    • 第二是管理内存中对象的分配,完成自动的垃圾回收;
    • 第三是优化热点代码提升执行效率 (JIT)。
  • JVM组成分为类加载子系统运行时数据区执行引擎本地接口这四部分。
  • 常用的JVM是Oracle提供的Hotspot虚拟机,也可以选择GraalVM、龙井(阿里)、OpenJ9等虚拟机。

2. 了解过字节码文件的组成吗?

答:

  • 字节码文件包括:
    • 基本信息:魔数,字节码文件对应的版本号、父类、接口等信息。
    • 常量池:保存了字符串常量、类或接口名、字段名等,主要在字节码指令中被引用。
    • 字段:当前类或接口声明的字段信息。
    • 方法:当前类或接口声明的方法中的字节码指令
    • 属性:类的属性。

可以使用 javap -v 字节码文件.Class 命令反编译查看对应字节码的信息

3. 什么是运行时数据区

答:

运行时数据区指的是JVM所管理的内存区域,其中分成两大类:

  • 线程共享
    • 堆内存:创建出来的对象都存在于堆上。静态变量也是在堆内存(Class对象中)。
    • 方法区:类的基础信息、运行时常量池(保存了字节码文件中的常量池内容)、字符串常量池
  • 线程不共享
    • 程序计数器:记录下一条要执行的字节码指令的地址。
    • Java虚拟机栈:记录执行方法的栈帧。
    • 本地方法栈:记录native本地方法的栈帧。

4. 哪些区域会出现内存溢出

答:

  • :溢出之后会抛出OutOfMemoryError,并提示是Java heap Space导致的。
    • 调整堆的大小:-Xmx值(max的最大值) -Xms值(初始的total)
  • :溢出之后会抛出StackOverflowError
    • 调整虚拟机栈的大小:-Xss栈大小
  • 方法区:溢出之后会抛出OutOfMemoryError,JDK7及之前提示永久代,JDK8及之后提示元空间
    • 调整永久代(-XX:MaxPermSize=值),调整元空间(-XX:MaxMetaspaceSize=值
  • 直接内存:溢出之后会抛出OutOfMemoryError
    • 调整直接内存: -XX:MaxDirectMemorySize=值

5. JVM在JDK6-8之间在内存区域上有什么不同

答:

  • JDK 6及之前,方法区的实现是在堆中的永久代
  • JDK 7,方法区中的字符串常量池被移到了堆中
  • JDK8及之后,堆中的永久代移除了,方法区移到了直接内存的元空间

  • 方法区的实现
    • JDK 7及之前:方法区是在堆中的永久代
    • JDK 8之后:方法区是在直接内存的元空间,永久代被移除
  • 字符串常量池的位置
    • JDK 6及之前:字符串常量池是在方法区上
    • JDK 7及之后:字符串常量池从方法区移除,放在堆中

6. 类的生命周期

答:

  • 加载
    • 类加载器根据类的全限定名以二进制流的方式获取字节码信息。
    • 方法区上创建类的信息。
  • 连接
    • 验证:验证字节码文件是否符合规范
    • 准备:为静态变量(static)分配内存并设置初值。final修饰的基本数据类型的静态变量,准备阶段直接会将代码中的值进行赋值。
    • 解析:将字节码文件中指向常量池中的符号引用替换为指向内存的直接引用
  • 初始化
    • 初始化阶段会执行静态代码块中的代码,并为静态变量赋值。注意:他们的执行顺序按编写的顺序加载。
    • 初始化阶段会执行字节码文件中clinit部分的字节码指令。
  • 卸载:同时满足以下3个条件可以被卸载
    • 此类所有实例对象都已经被回收,在堆中不存在任何该类的实例对象以及子类对象。
    • 加载该类的类加载器已经被回收。
    • 该类对应的 java.lang.Class 对象没有在任何地方被引用。

7. 什么是类加载器?类加载器有哪几种

答:

类加载器: 负责把字节码文件读取到JVM内存中。

  • 启动类加载器(Bootstrap):默认加载Java安装目录/jre/lib下的类文件,比如rt.jar,tools.jar,resources.jar等。
  • 扩展类加载器:默认加载Java安装目录/jre/lib/ext下的类文件
  • 应用程序类加载器:默认加载为应用程序classpath下的类文件。
  • 自定义类加载器:继承ClassLoader抽象类,重写findClass方法。在findClass方法中,定义从哪里读取字节码文件,然后调用defineClass方法,在方法区和堆区创建对象。

在这里插入图片描述

8. 什么是双亲委派机制?有什么好处

答:

  • 当一个类加载器要加载字节码文件时,首先向上查找父类加载器是否加载过,
  • 如果加载过,则直接返回。
  • 如果一直到顶级类加载器(Bootstrap)也没有加载过,则再从上至下尝试加载。

好处:

  • 保证JDK的核心类库不会被替换。
  • 避免类的重复加载

在这里插入图片描述

9. 如何打破双亲委派机制

答:

  • 实现自定义类加载器:首先继承ClassLoader抽象类,重写loadClass方法,将双亲委派机制的代码去除。
  • 然后编写从指定位置加载字节码,最后调用defineClass方法,在方法区和堆区创建对象。

在这里插入图片描述

10. 如何判断堆上的对象有没有被引用?

答:

可以使用引用计数法可达性分析法来判断

  • 引用计数法:每个对象都有一个引用计数器,当对象被引用时加1,取消引用时减1。为0时则说明没有被引用。缺点:存在循环引用。
  • 可达性分析法:将对象分类两类,根对象普通对象。从根对象(线程对象、静态变量、监视器对象等)出发,顺着引用链可以到达某个对象,则该对象说明被引用。

11. JVM 中都有哪些引用类型?

答:

  • 强引用:默认就是强引用,即对象被局部变量、静态变量所引用。强引用的对象不会被回收掉
  • 软引用:SoftReference类实现。当一个对象只被软引用对象引用,并且内存空间不足时,进行垃圾回收,则会回收被软引用指向的对象。可以把软引用对象本身放到引用队列中,回收软引用对象本身。
  • 弱引用:WeakReference类实现。不管内存空间够不够,在垃圾回收时,弱引用指向的对象都会被回收。弱引用对象本身也可以使用引用队列回收。
  • 虚引用:PhantomReference类实现。作用:告诉直接内存,当前指向直接内存的对象不再使用,将直接内存的空间进行回收。
  • 终结器引用:分两次垃圾回收才会把对象回收,不建议使用。

12. ThreadLocal中为什么要使用弱引用?

答:

  • 在ThreadLocal内部, 存放了一个ThreadLocalMap对象(哈希表),ThreadLocalMap中存放的是多个Entry对象。
  • 每个Entry对象继承自弱引用,指向ThreadLocal对象。同时强引用指向ThreadLocal对应的value值
  • 如果不使用弱引用的话,假如ThreadLocal对象不再使用了,那么ThreadLocal对象不会被回收,因为被Entry对象强引用。

在这里插入图片描述

13. 有哪些常见的垃圾回收算法?

答:

1、标记清除算法

根据可达性分析算法,将所有存活的对象进行标记

在清除阶段,将未被标记的对象进行清除

缺点: 容易产生大量的内存碎片

2、复制算法

将堆内存空间划分成两部分,from区和to区

新创建的对象会被放入到from区。进行垃圾回收的时候,将from区中存活的对象复制到to区

然后将from区和to区互相换个名字

缺点: 堆内存空间利用低

3、标记整理算法

根据可达性分析算法,将所有存活的对象进行标记

整理阶段,将所有存活的对象放到堆的一端,之后清理掉这些对象的内存。

缺点: 整理的效率低

4、分代垃圾回收

将堆内存分为新生代、老年代

新生代又分为:伊甸园、幸存区from、幸存区to

新创建的对象会被放到伊甸园中。

如果伊甸园满了,则会进行Minor GC。

将伊甸园和幸存区from中的存活对象复制到幸存区to中。

清理伊甸园和幸存区from。之后幸存区from、幸存区to互换名字

每次发生MInor GC时,存活的对象年龄 + 1,当到达15时,则会被放到老年代中。

如果老年代满了,首先会触发Minor GC,如果新生代还是放不下,则会触发Full GC。

如果Full GC之后,老年代还放不下,则会爆出OOM。

14. 分代GC算法为什么将堆分成新生代和老年代?

答:

  • 新生代和老年代可以使用不同的回收算法,更灵活。
  • 可以通过调整新生代和老年代大小的比例,来适应不同的应用程序。

15. 有哪些常用的垃圾回收器

答:

单线程的垃圾回收器:

  • Serial 回收新生代、采用复制算法
  • SerialOld 回收老年代、采用标记-整理算法
  • 缺点:吞吐量不如多线程的垃圾回收器。

多线程的垃圾回收器:

  • ParNew 回收新生代、采用复制算法
  • CMS(Concurrent Mark Sweep) 回收老年代、采用标记-清除算法
  • 会产生内存碎片

G1垃圾回收器

  • JDK 9之后,默认的垃圾回收器
  • 回收年轻代、老年代 采用复制算法

16. 内存泄漏的原因

答:

  • 大量的数据被静态变量长期引用。
  • 资源没有关闭

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

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

相关文章

React脚手架的搭建与使用

React脚手架是开发现代Web应用的必备,其充分利用Webpack、Babel、ESlint等工具辅助项目的开发,当然这些工具也无需手动配置即可使用,脚手架的意义更多的是关注的是业务而不是工具的配置;项目的整体技术架构为:react w…

OJ在线编程常见输入输出练习

文章目录 整型输入输出12345 字符串类型输入输出123 整型输入输出 1 #include <stdio.h>int main() {int a, b;while (scanf("%d %d", &a, &b) ! EOF) { if(a0 && b0)break;printf("%d\n", a b);}return 0; }2 #include <stdio…

服装连锁管理系统如何拓展会员?

在服装连锁店的经营管理中&#xff0c;会员制度是提升客户忠诚度、促进销售增长的重要手段之一。拓展会员对于连锁店来说至关重要&#xff0c;可以通过多种方式来吸引新会员并提升会员的活跃度。本文将探讨如何通过拓展会员来提升服装连锁店的经营效益&#xff0c;并提出四点建…

CSS 实现无限波浪边框卡片

CSS 实现无限波浪边框卡片 效果展示 鼠标悬停效果&#xff0c;底部色块的边框是无限滚动的波浪 鼠标没有悬停效果 CSS 知识点 CSS 基础知识回顾使用 radial-gradient 实现波浪边框使用 anumate 属性实现波浪边框动画和控制动画运动 波浪实现原理 波浪边框的实现思路其…

Axure RP中的相关概念及高保真原型构建方法

1 Axure RP中概念介绍 对于构建高保真原型来说&#xff0c;需要知道事件&#xff08;Event&#xff09;、Case、Action等概念。Axure RP中给出这些概念&#xff0c;是为了方便原型的构建&#xff0c;尤其是高保真原型的构建。 事件&#xff08;Event&#xff09;是附着于控件…

如何下载pycharm历史版本

地址&#xff1a;https://www.jetbrains.com/pycharm/download/other.html

GitHub repository - Pulse - Contributors - Network

GitHub repository - Pulse - Contributors - Network 1. Pulse2. Contributors3. NetworkReferences 1. Pulse 显示该仓库最近的活动信息。该仓库中的软件是无人问津&#xff0c;还是在火热地开发之中&#xff0c;从这里可以一目了然。 2. Contributors 显示对该仓库进行过…

蓝桥杯备赛:考前注意事项

考前注意事项 1、DevCpp添加c11支持 点击 工具 - 编译选项 中添加&#xff1a; -stdc112、万能头文件 #include <bits/stdc.h>万能头文件的缺陷&#xff1a;y1 变量 在<cmath>中用过了y1变量。 #include <bits/stdc.h> using namespace std;// 错误示例 …

基于java+springboot+vue实现的智能停车计费系统(文末源码+Lw+ppt)23-30

摘 要 随着人们生活水平的高速发展&#xff0c;智能停车计费信息管理方面在近年来呈直线上升&#xff0c;人们也了解到智能停车计费的实用性&#xff0c;因此智能停车计费的管理也逐年递增&#xff0c;智能停车计费信息的增加加大了在管理上的工作难度。为了能更好的维护智能…

智慧农业引领乡村全面振兴:数字乡村建设推动农业现代化、农村治理现代化与农民生活品质新提升

文章摘要&#xff1a; 随着信息技术的迅猛发展&#xff0c;智慧农业正成为引领乡村全面振兴的重要力量。数字乡村建设以智慧农业为核心&#xff0c;推动农业现代化、农村治理现代化和农民生活品质新提升。本文将从智慧农业的内涵出发&#xff0c;探讨数字乡村建设如何推动农业现…

机器学习周报第37周

目录 一、文献阅读&#xff1a;You Only Look Once: Unified, Real-Time Object Detection1.1 摘要1.2 背景1.3 论文模型1.4 网络设计1.5 YOLO的局限性1.6 实现代码 一、文献阅读&#xff1a;You Only Look Once: Unified, Real-Time Object Detection 1.1 摘要 YOLO是一种新…

3D Showroom Level Kit Vol 1

3D Showroom Level Kit Vol 1是一个预制PBR模块化套件,可帮助您创建任何大小、类型的展厅/关卡! 你想推广新产品吗?制作严肃游戏?展示你的艺术?照片?VR应用程序?你需要这个。。。 该工具包非常易于使用和定制!更改颜色和道具位置。 使用移动设备和VR设备,低多边形建…

Mapmost Alpha:开启三维城市场景创作新纪元

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【leetcode面试经典150题】49. 合并区间(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

Linux 硬链接和软链接怎么区分使用?

一、什么是硬链接和软链接 硬链接 在Linux操作系统中&#xff0c;硬链接相当于存储在硬盘驱动器中的文件&#xff0c;它实际上引用或指向硬盘驱动器上的某个点。硬链接是原始文件的镜像副本。 硬链接与软链接的区别在于&#xff0c;删除原始文件不会影响硬链接&#xff0c;但…

乐趣Python——办公魔法:Word文件自动化

嘿&#xff0c;朋友们&#xff01;在这个办公小课堂中&#xff0c;我将为大家揭开一个神奇的秘密&#xff1a;Word文件自动化处理&#xff01; 通过这种魔法般的方式&#xff0c;我们可以大大提高办公效率&#xff0c;减少重复性工作。而Python作为我们的助手&#xff0c;将展现…

AI大赏-一些关键词的出图效果展示

AI绘画 AI 绘画是利用人工智能技术来生成、转换或增强数字图像和艺术作品的过程。这种技术可应用于各种领域&#xff0c;包括数字媒体、游戏开发、电影制作、设计、视觉艺术等。 具体领域有图像生成、图像转换、图像增强、艺术创作&#xff0c;受影响比较到的是数字媒体&…

【嵌入式基础知识学习】AD/DA—数模/模数转换

AD/DA—数模/模数转换概念 数字电路只能处理二进制数字信号&#xff0c;而声音、温度、速度和光线等都是模拟量&#xff0c;利用相应的传感器&#xff08;如声音用话筒&#xff09;可以将它们转换成模拟信号&#xff0c;然后由A/D转换器将它们转换成二进制数字信号&#xff0c…

C语言: 字符串函数(下)

片头 在上一篇中,我们介绍了字符串函数。在这一篇章中&#xff0c;我们将继续学习字符串函数&#xff0c;准备好了吗&#xff1f;开始咯&#xff01; 1.strncpy函数 1.1 strncpy函数的用法 strncpy是C语言中的一个字符串处理函数&#xff0c;它用于将一个字符串的一部分内容…

Linux进阶篇:进程检测和控制:ps命令详细讲解

Linux进程检测和控制&#xff1a;ps命令详细讲解 一、ps命令介绍 Linux中的ps命令是Process Status的缩写。ps命令用来列出系统中当前运行的那些进程。ps命令列出的是当前那些进程的快照&#xff0c;就是执行ps命令的那个时刻的那些进程&#xff0c;如果想要动态的显示进程信…