Java面试题、八股文——JVM篇最终篇

1.如何选择垃圾收集器?

选择合适的垃圾收集器(Garbage Collector, GC)对于优化Java应用程序的性能至关重要。不同的应用场景和系统需求可能需要不同类型的垃圾收集器来满足。以下是一些考虑因素以及常见的垃圾收集器选项,帮助您做出选择:

考虑因素:

  • 应用响应时间:如果您正在构建一个需要低延迟的应用程序,例如在线交易系统或实时游戏,那么您可能需要选择能够最小化暂停时间的垃圾收集器。
  • 吞吐量:对于后台处理或者批处理任务来说,高吞吐量比低延迟更重要,这意味着您可以接受更长的垃圾回收暂停时间以换取更高的整体效率。
  • 内存占用:如果您的应用运行在资源受限的环境中,如嵌入式系统,则需要考虑垃圾收集器对内存使用的影响。
  • 堆大小:不同垃圾收集器对大堆和小堆的支持程度不同,选择时需要考虑您的应用预计使用的堆大小。
  • 并发性:现代垃圾收集器通常支持一定程度的并发操作,以减少对应用线程的影响。

常见的垃圾收集器

  • Serial Collector:适合于客户端场景,特别是小型应用或嵌入式系统。它使用单个线程进行垃圾回收,适用于单核处理器或内存有限的环境。
  • Parallel Collector(也称作Throughput Collector):通过多线程并行执行垃圾回收,旨在最大化应用的整体吞吐量。适合于多核处理器上的后台处理或批处理应用。
  • Concurrent Mark Sweep (CMS) Collector:旨在减少垃圾回收引起的暂停时间,适合于对响应时间有较高要求的应用。但它的缺点是可能会产生更多的内存碎片,并且在某些情况下会降低吞吐量。
  • G1 Collector(Garbage First):设计用于具有大堆的多核机器上运行的应用。它将堆划分为多个区域,并优先回收那些垃圾最多的区域,从而试图平衡吞吐量和响应时间。
  • ZGC 和 Shenandoah Collector:这两个都是实验性的垃圾收集器,设计目标是在大型堆上实现非常低的暂停时间(通常小于10毫秒)。它们特别适合于需要极低延迟的高性能应用。

如何选择:

  • 评估需求:首先明确您的应用对延迟、吞吐量、内存使用等方面的要求。
  • 测试与比较:在实际环境中测试不同的垃圾收集器,观察其对应用性能的影响。
  • 调优参数:根据测试结果调整垃圾收集器的相关参数,比如初始堆大小、最大堆大小等。
  • 持续监控:即使选择了垃圾收集器,也需要定期监控应用的性能指标,确保其始终符合预期。

2. 什么是类加载器?

类加载器(Class Loader)是Java虚拟机(JVM)的一部分,负责将字节码文件(.class 文件)加载到内存中,并转换成可以被虚拟机执行的方法区中的运行时数据结构。类加载器在Java中扮演着至关重要的角色,因为它不仅决定了应用程序如何访问类文件,还影响了类的可见性和安全性。

类加载器的工作机制

  • 加载:类加载器从文件系统、网络或其他来源读取类的二进制数据,并将其转换为方法区中的运行时数据结构。
  • 链接:包括验证、准备和解析三个步骤。
  • 验证:确保加载的类文件格式正确,没有安全问题。
  • 准备:为类的静态变量分配内存,并设置默认值。
  • 解析:将符号引用转换为直接引用,这个过程涉及到查找和替换类、接口、字段和方法的符号引用。
  • 初始化:执行类构造器 () 方法,即初始化类的静态变量和静态代码块。

类加载器的层次结构

Java中的类加载器采用了一种称为“双亲委派模型”的层级结构。这种模型确保了类加载过程的安全性和一致性。

  • Bootstrap ClassLoader:这是最顶层的类加载器,由C++编写,不是Java类的一部分。它负责加载核心Java类库(如 java.lang.*),位于 rt.jar 中。
  • Extension ClassLoader(扩展类加载器):负责加载标准扩展库中的类,通常位于 $JAVA_HOME/lib/ext 目录下。
  • Application ClassLoader(应用类加载器):也称为系统类加载器,负责加载应用程序的类路径(classpath)中指定的类文件。

自定义类加载器

除了上述内置的类加载器外,开发人员还可以创建自定义类加载器来实现特定的功能,如从网络加载类、加密类文件等。自定义类加载器通常继承自 java.lang.ClassLoader 类,并重写 findClass() 或 loadClass() 方法。

双亲委派模型

双亲委派模型是指当一个类加载器收到类加载请求时,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的Bootstrap类加载器中。只有当父类加载器无法加载该类(即在其加载范围之外)时,子加载器才会尝试自己加载。

这种模型的好处在于:

  • 安全性:防止用户自定义的类伪装成核心类库中的类,因为核心类库总是先被加载。
  • 避免重复加载:保证所有加载器之间的类加载协调一致,避免同一个类被多次加载。

3.什么是 tomcat 类加载机制?

Tomcat 是一个广泛使用的开源 Servlet 容器,它支持 Java Servlet 和 JavaServer Pages (JSP) 技术。Tomcat 的类加载机制是其核心功能之一,它确保了不同Web应用程序之间的隔离性和安全性。以下是关于 Tomcat 类加载机制的详细介绍:

类加载器层次结构
Tomcat 采用了类似于 Java 标准的双亲委派模型,但为了适应 Web 应用程序的需求,增加了一些额外的类加载器。以下是 Tomcat 类加载器的层次结构:

  • Bootstrap ClassLoader
    • 这是最顶层的类加载器,负责加载核心的 Java 类库,如 java.lang.*。
    • 通常由 JVM 提供,不是 Java 类的一部分。
  • System ClassLoader(也称为 Application ClassLoader)
    • 负责加载应用程序的类路径(classpath)中指定的类文件。
    • 包括 JDK 的扩展库(如 $JAVA_HOME/lib/ext 目录下的类)。
  • Common ClassLoader
    • 加载 $CATALINA_HOME/lib 目录下的类文件。
    • 这些类对所有 Web 应用程序都是可见的。
  • Catalina ClassLoader
    • 加载 $CATALINA_HOME/server 目录下的类文件。
    • 这些类仅对 Tomcat 服务器内部使用,对 Web 应用程序不可见。
  • Shared ClassLoader
    • 加载 $CATALINA_HOME/shared 目录下的类文件。
    • 这些类对所有 Web 应用程序都是可见的,但不推荐使用,因为这可能导致类加载冲突。
  • WebApp ClassLoader
    • 每个 Web 应用程序都有自己的 WebApp ClassLoader。
    • 负责加载 Web 应用程序的 WEB-INF/classes 目录和 WEB-INF/lib 目录下的类文件。
    • 这些类只对当前 Web 应用程序可见,实现了应用程序之间的隔离。

类加载顺序

Tomcat 的类加载顺序遵循以下规则:

双亲委派模型:

  • 当一个类加载器收到类加载请求时,它首先会委托给父类加载器去加载。
  • 只有当父类加载器无法加载该类时,子类加载器才会尝试加载。
    WebApp ClassLoader 的特殊行为
  • WebApp ClassLoader 在某些情况下会优先加载本地类,而不是委托给父类加载器。
  • 这是为了允许 Web 应用程序覆盖 Tomcat 或 JDK 中的类,尽管这种做法并不推荐。

示例

假设有一个 Web 应用程序部署在 Tomcat 上,其类加载路径如下:

  • Bootstrap ClassLoader:加载核心 Java 类库。
  • System ClassLoader:加载 JDK 扩展库和应用程序类路径中的类。
  • Common ClassLoader:加载 $CATALINA_HOME/lib 目录下的类。
  • WebApp ClassLoader:加载 WEB-INF/classes 和 WEB-INF/lib 目录下的类。

当应用程序请求加载某个类时,类加载器的查找顺序如下:

  • Bootstrap ClassLoader 尝试加载。
  • 如果未找到,System ClassLoader 尝试加载。
  • 如果未找到,Common ClassLoader 尝试加载。
  • 如果未找到,WebApp ClassLoader 尝试加载。

注意事项

类加载冲突

  • 避免在 WEB-INF/lib 或 WEB-INF/classes 中包含与 Tomcat 或 JDK 冲突的类。
  • 使用 shared 目录时要特别小心,因为这可能导致类加载冲突。

类加载器隔离

  • 每个 Web 应用程序的 WebApp ClassLoader 是独立的,确保了不同应用程序之间的类隔离。

性能优化:

  • 合理组织类文件的位置,避免不必要的类加载,可以提高应用程序的启动和运行性能。

通过理解和合理配置 Tomcat 的类加载机制,可以有效地管理 Web 应用程序的类加载行为,确保应用程序的稳定性和性能。

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

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

相关文章

k8s网络服务

k8s 中向外界提供服务的几种方法port-forward、NodePort,以及 更加常用的提供服务的资源ingress。 1 kubectl port-forward service/redis 6379:6379 现在k8s中有一个pod运行在6379,本机访问映射到6379上,它可以针对部署,服务&…

eduSRC挖洞思路

声明 学习视频来自 B 站UP主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 ✍🏻作者简介:致…

Leetcode - 周赛424

目录 一,3354. 使数组元素等于零 二, 3355. 零数组变换 I 三,3356. 零数组变换 II 四,3357. 最小化相邻元素的最大差值 一,3354. 使数组元素等于零 本题实际上是一个前/后缀和的问题,就是判断前缀和与后…

Vue2中 vuex 的使用

1.安装 vuex 安装vuex与vue-router类似,vuex是一个独立存在的插件,如果脚手架初始化没有选 vuex,就需要额外安装。 yarn add vuex3 或者 npm i vuex3 233 Vue2 Vue-Router3 Vuex3 344 Vue3 Vue-Router4 Vuex4 2. 新建 store/index.j…

数据结构C语言描述5(图文结合)--队列,数组、链式、优先队列的实现

前言 这个专栏将会用纯C实现常用的数据结构和简单的算法;有C基础即可跟着学习,代码均可运行;准备考研的也可跟着写,个人感觉,如果时间充裕,手写一遍比看书、刷题管用很多,这也是本人采用纯C语言…

Windows修复SSL/TLS协议信息泄露漏洞(CVE-2016-2183) --亲测

漏洞说明: 打开链接:https://docs.microsoft.com/zh-cn/troubleshoot/windows-server/windows-security/restrict-cryptographic-algorithms-protocols-schannel 可以看到: 找到:应通过配置密码套件顺序来控制 TLS/SSL 密码 我们…

深度学习图像视觉 RKNN Toolkit2 部署 RK3588S边缘端 过程全记录

深度学习图像视觉 RKNN Toolkit2 部署 RK3588S边缘端 过程全记录 认识RKNN Toolkit2 工程文件学习路线: Anaconda Miniconda安装.condarc 文件配置镜像源自定义conda虚拟环境路径创建Conda虚拟环境 本地训练环境本地转换环境安装 RKNN-Toolkit2:添加 lin…

controller中的参数注解@Param @RequestParam和@RequestBody的不同

现在controller中有个方法:(LoginUserRequest是一个用户类对象) PostMapping("/test/phone")public Result validPhone(LoginUserRequest loginUserRequest) {return Result.success(loginUserRequest);}现在讨论Param("login…

Android按键点击事件三种实现方法

1. 在xml文件中为 Button 添加android:onclick属性 由于没有onclick这个函数,onclick下面会提示红色波浪线错误,然后单击一下"onclick"按住键盘上AltEnter键,选择在activity中生成函数 public void onclick(View view) {Toast.makeText(this,&…

全景图像(Panorama Image)向透视图像(Perspective Image)的跨视图转化(Cross-view)

一、概念讲解 全景图像到透视图像的转化是一个复杂的图像处理过程,它涉及到将一个360度的全景图像转换为一个具有透视效果的图像,这种图像更接近于人眼观察世界的方式。全景图像通常是一个矩形图像,它通过将球面图像映射到平面上得到&#xf…

RabbitMQ7:消息转换器

欢迎来到“雪碧聊技术”CSDN博客! 在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将…

C#开发合集

用C#轻松搞定m3u8视频下载与合并 嘿,程序员们!今天咱们来聊聊如何用C#写个小程序,轻松下载和合并m3u8视频文件。没错,就是那种分段的流媒体视频。准备好了吗?让我们开始吧! 准备工作 在动手之前&#xf…

HarmonyOS4+NEXT星河版入门与项目实战(22)------动画(属性动画与显示动画)

文章目录 1、属性动画图解2、案例实现-小鱼移动游戏1、代码实现2、代码解释3、资源图片4、实现效果3、显示动画4、案例修改-显示动画5、总结1、属性动画图解 这里我们用一张完整的图来汇整属性动画的用法格式和使用的主要属性范围,如下所示: 2、案例实现-小鱼移动游戏 1、代…

【rustdesk】客户端和服务端的安装和部署(自建服务器,docker,远程控制开源软件rustdesk)

【rustdesk】客户端和服务端的安装和部署(自建服务器,docker) 一、官方部署教程 https://rustdesk.com/docs/zh-cn/client/mac/ 官方服务端下载地址 https://github.com/rustdesk/rustdesk-server/releases 我用的docker感觉非常方便&am…

Qt程序发布及打包成exe安装包

参考:Qt之程序发布以及打包成exe安装包 目录 一、简述 Qt 项目开发完成之后,需要打包发布程序,而因为用户电脑上没有 Qt 配置环境,所以需要将 release 生成的 exe 文件和所依赖的 dll 文件复制到一个文件夹中,然后再用 Inno Setup 打包工具打包成一个 exe 安装包,就可以…

python学opencv|读取图像

【1】引言 前序学习了使用matplotlib模块进行画图,今天开始我们逐步尝试探索使用opencv来处理图片。 【2】学习资源 官网的学习链接如下: OpenCV: Getting Started with Images 不过读起来是英文版,可能略有难度,所以另推荐一…

数据结构 ——— 归并排序算法的实现

目录 归并排序的思想 归并排序算法的实现 归并排序的思想 将已经有序的子序列合并,得到完全有序的序列,即先使每个子序列有序后,再使子序列段间有序 若将两个有序表合并成一个有序表,称为二路归并 归并排序步骤示意图&#x…

Springboot项目搭建(6)-前端登录跳转与Pinia实用

1.添加响应错误拦截 文件地址:src\utils\request.js import axios from axios import { ElMessage } from element-plus const baseURL /api const instance axios.create({baseURL}) //添加拦截器 instance.interceptors.response.use(result>{&#x1f447…

多输入多输出 | Matlab实现TCN-LSTM时间卷积神经网络结合长短期记忆神经网络多输入多输出预测

多输入多输出 | Matlab实现TCN-LSTM时间卷积神经网络结合长短期记忆神经网络多输入多输出预测 目录 多输入多输出 | Matlab实现TCN-LSTM时间卷积神经网络结合长短期记忆神经网络多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现…

C++网络编程:select IO多路复用及TCP服务器开发

C网络编程:使用select实现IO多路复用 一、什么是 IO 多路复用?二、IO多路复用器 select三、相关接口3.1、fd_set 结构体3.2、宏和函数 四、select 实现 TCP 服务器五、总结 一、什么是 IO 多路复用? 在网络编程中,最容易想到的并…