Java面试题——第八篇(JVM)

news2024/12/23 18:50:46

1. JVM中有哪些垃圾回收算法

Java中的垃圾回收算法有以下几种

1. 标记-清除算法

  • 工作原理:首先遍历堆中的对象,标记出所有存活的对象,接着清除未标记的对象。
  • 优点:实现简单,能够处理堆中的所有对象
  • 缺点:标记和清除的过程会产生内存碎片,影响后续内存分配的效率

2. 标记-整理算法

  • 工作原理:首先标记出所有存活的对象,然后将存活的对象整理到一边,最后清除未标记的对象
  • 优点:避免了内存碎片问题
  • 缺点:整理阶段需要移动对象,会导致额外的开销

3. 复制算法

  • 工作原理:将内存分为两部分,每次只使用其中一半,垃圾回收时将存活的对象从一半复制到另一半,清除原区域的所有对象。
  • 优点:无需处理内存碎片,分配效率高
  • 缺点:需要双倍的内存空间,浪费了一半的空间

2. JVM的TLAB是什么

TLAB是JVM中为每个线程分配的一小块堆内存,用于加速对象的分配操作。每个线程都有自己的TLAB,大大加速了内存分配的同时避免了多线程竞争共享堆内存时的同步开销。

工作原理:

  • 每个线程在执行过程中有先从自己的TLAB中分配内存
  • 当TLAB内存耗尽时,线程会重新向Eden区申请一个新的TLAB,或者直接从Eden区分配内存
  • 对象超过一定大小时(大对象),不会在TLAB中分配,而是直接在Eden区分配

3. Java是如何实现跨平台的

Java程序在编译后生成字节码(.class文件),而不是直接生成特定于某一操作系统的机器代码。

在不同操作系统上都有各自实现的JVM,负责将字节码翻译为特定平台的机器代码并执行。使得同一份Java字节码可以在任何支持的JVM平台上运行。

4. 编译执行和解释执行的区别是什么?JVM使用哪种方式

编译执行:指程序在执行之前,首先通过编译器将源代码编译为机器代码。然后直接在CPU上运行。如C、C++。

  • 优点:编译后的程序运行速度快,因为机器代码是针对目标平台直接生成的,且不需要在运行时在进行翻译。
  • 缺点:程序必须针对每个平台重新编译,跨平台性差;另外,编译后生成的机器代码难以调试和逆向工程。

解释执行:解释执行指源代码不经过编译器的预先编译,而是在运行时通过解释器逐行翻译并执行。常见的解释语言如python、ruby。

  • 优点:跨平台性好,因为代码在每个平台上都是通过相应平台的解释器来运行的,且开发周期更短。
  • 缺点:运行速度较慢,因为每次执行时都需要进行动态翻译和解释。

JVM采用 编译执行解释执行 相结合的方式:

  • 解释执行:JVM会逐行解释执行字节码,尤其是程序初次运行时,这种方式有助于程序的跨平台性。
  • 即时编译(JIT):JVM引入了即时编译器,在程序运行时将热代码编译为本地机器码,避免反复解释,提升性能。

5. JVM的内存区域如何划分

Java虚拟机运行时数据区域划分为方法区、堆、虚拟机栈、本地方法栈、程序计数器。

  1. 方法区
  • 存储类信息、常量、静态变量和即时编译器编译后的代码
  • 属于线程共享区域,所有线程共享方法区内存
  • 在JDK8 之前,HotSpot使用永久代(PermGen)实现方法区,JDK8之后被元空间取代,元空间使用的是直接内存。
  • 用于存放所有线程共享的对象和数组,是垃圾回收的主要区域
  1. 虚拟机栈
  • 每个线程创建一个栈,用来保存局部变量、操作数栈、动态链接、方法出口信息等。
  • 局部变量表中存储的是基本数据类型以及对象引用
  • 栈是线程私有的,生命周期和线程相同
  1. 本地方法栈
  • 为本地方法服务,使用JNI调用的本地代码在此区域分配内存
  • 和虚拟机栈类似,也是线程私有的
  1. 程序计数器
  • 是一个小的内存区域,保存当前线程执行的字节码指令的地址或者行号
  • 每个线程都有一个独立的程序计数器,属于线程私有

还有一个直接内存,他属于JVM之外的内存区域:

  • 由NIO库通过ByteBuffer直接分配的内存
  • 直接内存的大小不受堆内存限制,但会收到本机内存的限制

6. Java中堆和栈的区别是什么

栈:主要用于存储局部变量和方法的调用信息(如返回地址、参数等)。在方法执行期间,局部变量被创建在栈上,并在方法结束时被销毁。

堆:用于存储对象实例和数组,每当使用new关键字创建对象时,jvm都会在堆上为该对象分配内存空间。

从其他方面进一步区分

  • 生命周期:JVM里面的垃圾回收主要是对堆空间的处理,而栈空间是不会被回收的,所以栈空间的生命周期都非常短,比如一次方法的调用,调用的时候存入,执行完成就弹出。而堆空间是需要通过GC进行回收的,所以堆空间的生命周期会相对较长。

如果是引用数据类型,比如A a = new A(); 这种a分配到栈空间是一个地址,指向堆中的实例化的A。
如果A中定义了一个属性 B b = new B();这个b并不会存在栈空间,而是直接放在堆空间,存储的是实例化的B的地址。

7. 什么是Java中的直接内存

Java中的直接内存是由操作系统分配的内存区域,不受JVM堆内存管理限制。直接内存通过java.nio包中的ByteBuffer.allocateDirect()方法分配,可以绕过JVM垃圾回收机制,直接与本地系统内存交互。

1. 直接内存的优势
由于直接内存不需要在堆上进行分配和复制数据,因此和操作系统的IO操作时可以减少一次复制。提升性能,在文件读写和网络传输场景直接内存有很大的优势。
2. 性能优化策略

  • 使用缓存机制:可以缓存ByteBuffer.allocateDirect()分配的缓冲区,减少频繁的直接内存分配。
  • 合理设置JVM参数:堆外内存不归JVM设置的堆大小限制,但是可以通过设置-XX:MaxDirectMemorySize来设置内存的最大使用量,避免不必要的内存消耗。

3. 直接内存和堆内存的区别

  • 分配位置:堆内存由JVM管理,受GC控制;直接内存由操作系统分配,使用本地内存
  • 访问速度:直接内存的访问速度在特定场景下更快,因为减少了堆内存到本地内存的复制。
  • 回收机制:堆内存由垃圾回收器挥手,而直接内存的回收需要通过调用ByteBuffer的cleaner方法进行清理。

8. 什么是Java中的常量池

Java中的常量池是一块用于存储运行时的常量或者符号的区域。主要存在于两种地方

  • 运行时常量池:在每个类或接口的class文件中存储编译时生成的常量信息,并在类加载时进入JVM方法区。
  • 字符串常量池:用于存储字符串字面量,位于堆内存中的一块特殊区域,通过String类中的intern方法可以讲字符串加入到字符串常量池。

常量池的作用:

  • 常量池用于减少重复对象的创建,节省内存并提高效率。在Java编译过程中,一些常用的常量如字符串、基本类型等会存储在常量池中,避免重复创建相同的常量。

1. 字符串常量池和堆内存
在Java中,字符串的创建方式有两种

  • 直接使用字面量:String s = “Hello”;会将 "Hello"存储在常量池中,如果常量池中已存在 “Hello”,则不会重复创建。
  • 使用new关键字:String s = new String(“Hello”);会在堆中创建一个新的String对象,而不涉及常量池。

9. Java的类加载器

Java的类加载器是JVM中用于动态加载类文件的组件。他将.class文件中的字节码加载到内存中,并将其转换为class对象,以供JVM执行。

类加载器的作用:

  • 动态加载类:在运行时根据需要加载类,而不是在编译时加载所有类。
  • 隔离不同的类命名空间:通过不同的类加载器,可以隔离同名类,使得他们不会相互冲突。

类加载器的层次结构
JDK8的时候一共有三种类加载器

  • 启动类加载器:属于虚拟机自身的一部分,用C++实现的,是所有类加载器的父亲。
  • 扩展类加载器
  • 应用程序类加载器:Java实现,独立于虚拟机,主要负责加载用户类路径上的类库。如果,我们没有实现自定义的类加载器那这个加载器就是我们程序中的默认加载器。

在这里插入图片描述

9. Java类加载过程

类加载指的是把类加载到JVM中,把二进制流存储到内存中,之后经过一番解析,处理转化成可用的class类。二进制流来源于class文件,或通过字节码工具生成的字节码或来自于网络,只要符合格式的二进制流。JVM来者不拒。

类加载过程分为

  • 加载
  • 连接
  • 初始化

连接还能拆分为:验证、准备、解析三个阶段。

所以,总的来看,类加载过程分为5个阶段

  • 加载:将二进制流读入内存中,生成一个Class对象。
  • 验证:主要是验证加载进来的二进制流是否符合一定格式,是否规范,是否符合当前JVM版本等等之类的验证。
  • 准备:为静态变量赋初始值,也即为他们在方法区划分内存空间。这里注意是静态变量,并且是初始值,比如int的初始值是0.
  • 解析:将常量池的符号引用转化成直接引用。符号引用可以理解为一个字面量,直接引用指的是一个真实引用。
  • 初始化:执行一些静态代码块,为静态变量赋值,这里的赋值才是代码里面的赋值。准备阶段只是设置初始值占个坑。

10. 什么是Java中的JIT

Java中的JIT编译器是一种在 程序运行时将字节码转换为机器码的技术。在Java程序运行的时候,发现热点代码时,将这段代码编译成机器码,减少解释执行的开销。

11. 什么是Java的AOT

Java的AOT是一种在程序运行之前,将Java字节码直接编译为本地机器码的技术。JIT是在Java运行时将一些代码编译成机器码,而AOT是在代码运行之前就编译成机器码。

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

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

相关文章

vue3 antd-design-vue3 日期组件语言不显示中文问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、修改步骤 前言 随着ant-design-vue v3的推出,ant-design-vue官方把时间组件中的momentjs 替换成了dayjs,升级完后发现日期显示不正…

swift使用internvl2微调ocr文字检测(目标检测)

详细记录swfit微调interVL2-8B多模态大模型进行目标检测(附代码)-CSDN博客文章浏览阅读2k次,点赞45次,收藏14次。目标检测任务已经不是一个新鲜事了,但是多模态大模型作目标检测任务并不多见,本文详细记录swfit微调interVL2-8B多模态大模型进行目标检测的过程,旨在让更多…

Linux驱动开发(速记版)--单总线

第124章 单总线简介 124.1 单总线概述 单总线是一种串行通信协议,由Dallas Semiconductor开发,特点是用一根信号线实现双向数据传输和时钟同步,节省IO口且结构简单。 它广泛应用于传感器、存储器等。 硬件包括信号线、上拉电阻、设备和处理器…

代码随想录--字符串--重复的子字符串

题目 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。 示例 1: 输入: "abab" 输出: True 解释: 可由子字符串 "ab" 重复两次构成。示例 2: 输入: "…

javaweb - 请求响应代码实现

简单参数 原始方式 在原始的web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取。 RequestMapping("/simpleParam")public String simpleParam(HttpServletRequest request) {String name request.getParameter("name&…

基于Springboot+Vue的养老院管理系统的设计与实现 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

TMC2209堵转检测配置详细教程

按如下图将TMC2209和串口模块连接: 配置流程: 寄存器配置: 通用寄存器: 校验码见我之前文章:使用uart串口配置TMC2209模块_tmc2209 uart-CSDN博客 通用寄存器主要是配置第0和第1位,第1位要给1&#xff0…

python之详解列表

有序的可变容器,可以存储不同类型的元素。用中括号[]表示。 1、列表的查找访问 1.1、通过下标查找。 与字符串类似,列表也可通过 列表名[index] 的方式查找其中的元素。 索引的初始值为0,最大值为列表长度-1。 示例: list1 …

刷题 位运算 / 数学

面试经典 150 题 - 位运算 ⭐️⭐️67. 二进制求和 加法进位 class Solution { public:string addBinary(string a, string b) {int na a.size(), nb b.size();string ans;ans.reserve(max(na, nb) 1); // 预留空间,避免动态扩展时的性能损耗int carry 0;for …

platform bus平台总线详解

往期内容 驱动中的device和device_driver结构体-CSDN博客bus总线的相关结构体和注册逻辑-CSDN博客bus中设备驱动的probe触发逻辑和device、driver的添加逻辑-CSDN博客 前言 注:以下的代码皆摘自于linux 4.9.88版本的内核源码,不同版本可能有所出入。 之…

【EXCEL数据处理】保姆级教程 000016案例 EXCEL的vlookup函数。

【EXCEL数据处理】000016案例 vlookup函数。 前言:哈喽,大家好,今天给大家分享一篇文章!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【EXCEL数据处理】保姆级教…

【动态规划】斐波那契模型 dp

动态规划的步骤: 状态表示。所谓状态表示就是 dp 表里的值表示什么含义,那么状态表示怎么找呢? a. 题目要求 b. 经验(以某一个位置为结尾 / 起点) 题目要求 c. 分析问题的过程中发现重复子问题状态转移方程。dp[ i ] …

ChatGPT Canvas:系统提示词泄漏了~

OpenAI 推出了一款叫做 Canvas 的新工具,用来帮助用户更好地与 ChatGPT 协作写作和编程。详细介绍可以看这篇文章:ChatGPT Canvas:交互式对话编辑器-CSDN博客​编辑 以下是 OpenAI 新功能 “Canvas” 的系统提示内容 你是 ChatGPT&#xff0…

基于连续小波变换(CWT)批量生成一维信号的时频图 最终生成30张时频图。生成的图像可用于后续的深度学习分类或其他处理。附详细的说明文档。

Matlab基于连续小波变换(CWT),将一维信号批量生成时频图的源代码。此示例中,原始信号data是30*1280的格式,一共30条信号,信号长度为1280。最终生成30张时频图。生成的图像可用于后续的深度学习分类或其他处…

SpringBoot开发——SpringSecurity安全框架17个业务场景案例(二)

文章目录 一、Spring Security 常用应用场景介绍二、Spring Security场景案例6、CSRF 保护(CSRF Protection)6.1 Spring Security 配置6.2 业务逻辑代码7、密码编码(Password Encoding)7.1 Spring Security 配置7.2 业务逻辑代码7.3 控制器8、方法级安全性(Method Securit…

Vue2电商项目(八) 完结撒花:图片懒加载、路由懒加载、打包的map文件

一、图片懒加载 安装:npm i vue-lazyload1.3 -s (弹幕建议按1.3版本) 引入 // 引入懒加载的图片 import hlw from /assets/hulu.jpg // 引入插件 import VueLazyload from vue-lazyload // 引入插件 Vue.use(VueLazyload, {// 懒加载默认的图…

Oracle登录报错-ORA-01017: invalid username/password;logon denied

接上文:Oracle创建用户报错-ORA-65096: invalid common user or role name 我以为 按照上文在PDB里创建了用户,我以为就可以用PLSQL远程连接了,远程服务器上也安装了对应版本的Oracle客户端,但是我想多了,客户只是新建…

【爬虫】网站反debugger、内存爆破以及网站限制开发者工具

【爬虫】网站反debugger、内存爆破以及网站直接限制开发者工具 声明:本文中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途&#xff0…

JWT集成Keycloak

一、直接使用现有域账号、密码获取token方式 1.KeyClack 使用现有配置 Client id : account-console 2.服务配置文件配置 3.API接口配置 4. 获取token 5.调用方式(Swagger)(代码方式直接在请求头加上token) 5.1 配置在Swagger访问 5.2 访问需要认证的接…

JavaWeb——Vue路由(概述、介绍、使用、解决bug)

目录 概述 介绍 使用 解决bug 概述 员工管理的页面已经制作完成。其他页面的制作方式一致。 项目中准备了部门管理的页面组件 DeptView ,这样就有了员工管理和部门管理两个页面组件。 在系统中,要实现点击部门管理菜单展示部门管理组件&#xff0c…