【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. 内存泄漏的原因

答:

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

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

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

相关文章

“国字号”荣誉、全国试点,侨乡群众身边的“放心”公证处

日前,我市五邑公证处获评“全国公共法律服务工作先进集体”称号。 走进公证处,首先映入眼帘的是一间宽敞明亮的大厅,办证点内还设置多个独立办证室,工作人员热情地为前来办理业务的市民提供专业、人性化的公证服务。江门市五邑公证…

Windows上面搭建Flutter Android运行环境

Flutter Android环境搭建 电脑上面安装配置JDK电脑上下载安装Android Studio电脑上面下载配置Flutter Sdk (避坑点一)下载SDK配置对应的环境变量 到path 电脑上配置Flutter国内镜像运行 flutter doctor命令检测环境是否配置成功创建运行Flutter项目&…

ARM单片机的GPIO口在控制不同LED、按键时的设置

个人备忘,不喜勿喷。 GPIO口在驱动共阴极、共阳极LED灯时需要不同的初始化设置 对于这一类的led灯: 最好选择推挽、上拉、高速输出,同时IO口初始化时需要拉高。 上面这种需要下拉输入; 上图这种需要上拉输入,这样才…

vue点击上传图片并实现图片预览功能,并实现多张图片放到一个数组中进行后端请求(使用原生input)

一、将 File 对象转成 BASE64 字符串 &#xff08;FileReader&#xff09; <template><div><!-- 用来显示封面的图片 --><!-- <img src"/assets/images/cover.jpg" alt"" class"cover-img" ref"imgRef" />…

html基础(2)(链接、图像、表格、列表、id、块)

1、链接 <a href"https://www.example.com" target"_blank" title"Example Link">Click here</a> 在上示例中&#xff0c;定义了一个链接&#xff0c;在网页中显示为Click here&#xff0c;鼠标悬停指示为Example Link&#xff0c…

Java(多线程)

一、基本概念 进程&#xff1a;一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元&#xff0c;在传统的操作系统中&#xff0c;进程既是基本的分配单元&#xff0c;也是基本的执行单元。线程&#xff1a;操作系统中能够进行运算的最…

java Web课程管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 课程管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使用ja…

贪心算法|406.根据身高重建队列

力扣题目链接 class Solution { public:static bool cmp(const vector<int>& a, const vector<int>& b) {if (a[0] b[0]) return a[1] < b[1];return a[0] > b[0];}vector<vector<int>> reconstructQueue(vector<vector<int>…

骑砍2霸主MOD开发(2)-基础开发环境搭建

一.骑砍2霸主程序架构 二.骑砍2霸主C#接口层代码查看 1.C#反编译工具dnspy下载: 2.骑砍2霸主游戏引擎接口查看: 例如IMBAgent interface接口: #调用TaleWorlds.Native.dll中的函数 [EngineMethod("get_movement_flags", false)] uint GetMovementFlags(UIntPtr agen…

Visual Studio Code SSH 连接远程服务器

Visual Studio Code通过 SSH 连接远程服务器并实现免密登录&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. **安装插件**&#xff1a;首先&#xff0c;在 VS Code 中安装 "Remote - SSH" 插件。打开 VS Code&#xff0c;点击左侧的扩展图标&#xff0c;搜索…

微服务学习3

目录 1.微服务保护 1.1.服务保护方案 1.1.1.请求限流 1.1.2.线程隔离 1.1.3.服务熔断 1.2.Sentinel 1.2.1.微服务整合 1.2.2.请求限流 1.3.线程隔离 1.3.1.OpenFeign整合Sentinel 1.3.2.配置线程隔离 1.4.服务熔断 1.4.1.编写降级逻辑 1.4.2服务熔断 2.分布式事…

mp4转flv怎么转?电脑怎么把视频转成flv?

MP4&#xff08;MPEG-4 Part 14&#xff09;是一种多媒体容器格式&#xff0c;广泛用于包含视频、音频、字幕等多种数据流。MP4因其高度灵活性、压缩效率和兼容性成为视频领域的主流格式&#xff0c;支持范围涵盖从在线视频到移动设备的各类应用场景。 FLV文件格式的多个优点 …

scFed:联邦学习用于scRNA-seq分类

scRNA-seq的出现彻底改变了我们对生物组织中细胞异质性和复杂性的理解。然而&#xff0c;大型&#xff0c;稀疏的scRNA-seq数据集的隐私法规对细胞分类提出了挑战。联邦学习提供了一种解决方案&#xff0c;允许高效和私有的数据使用。scFed是一个统一的联邦学习框架&#xff0c…

Spring Validation解决后端表单校验

NotNull&#xff1a;从前台传递过来的参数不能为null,如果为空&#xff0c;会在控制台日志中把message打印出来 Range&#xff1a;范围&#xff0c;最大多少&#xff0c;最小多少 Patten&#xff0c;标注的字段值必须符合定义的正则表达式&#xff08;按照业务规则&#xff0…

Android OOM问题定位、内存优化

一、常用工具&#xff1a; 1、LeakCanary val refWatcher: RefWatcher? TestApp.getRefWatcher(activity) refWatcher?.watch(activity);//检测是否有泄露&#xff0c;即触发GC回收&#xff0c;看activity是否被回收&#xff0c;没有被回收就是泄露了。 二、常见的几种内…

TCP 重传、滑动窗口、流量控制、拥塞控制(计算机网络)

重传机制 TCP 针对数据包丢失的情况&#xff0c;会用重传机制解决。 接下来说说常见的重传机制&#xff1a; 超时重传快速重传SACKD-SACK 超时重传 重传机制的其中一个方式&#xff0c;就是在发送数据时&#xff0c;设定一个定时器&#xff0c;当超过指定的时间后&#xff0c…

实验2 路由器基本配置

实验2 路由器基本配置 一、 原理描述二、 实验目的三、 实验内容四、 实验步骤1.建立实验拓扑2.基础配置3.配置路由器接口IP地址4.查看路由器配置信息5.连通性测试6.使用抓包工具 一、 原理描述 华为设备支持多种配置方式&#xff0c;操作人员要熟悉使用命令行的方式进行设备管…

SecureCRT通过私钥连接跳板机,再连接到目标服务器(图文教程)

文章目录 1. 配置第一个session&#xff08;跳板机&#xff09;2. 设置本地端口3. 设置全局firewall4. 配置第二个session&#xff08;目标服务器&#xff09; 服务器那边给了一个私钥&#xff0c;现在需要通过私钥连接跳板机&#xff0c;再连接到目标服务器上 &#x1f349; …

算法打卡day40|动态规划篇08| Leetcode 139.单词拆分|多重背包理论|背包问题总结篇

目录 算法题 Leetcode 139.单词拆分 个人思路 解法 动态规划 回溯法 多重背包理论基础 背包问题总结篇 解题思路 背包递推公式 遍历顺序 01背包 完全背包 算法题 Leetcode 139.单词拆分 题目链接:139.单词拆分 大佬视频讲解&#xff1a;单词拆分视频讲解 个人思…

Redis系列之基于Linux单机安装

Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库&#xff0c;并提供多种语言的 API。最近学习需要用到Redis&#xff0c;所以就去Linux服务器上部署一个&#xff0c;做下记录&#xff0c;方便…