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 应用程序的类加载行为,确保应用程序的稳定性和性能。
相关文章:
Java面试题、八股文——JVM篇最终篇
1.如何选择垃圾收集器? 选择合适的垃圾收集器(Garbage Collector, GC)对于优化Java应用程序的性能至关重要。不同的应用场景和系统需求可能需要不同类型的垃圾收集器来满足。以下是一些考虑因素以及常见的垃圾收集器选项,帮助您做…...
Spring Boot整合Redis Stack构建本地向量数据库相似性查询
Spring Boot整合Redis Stack构建本地向量数据库相似性查询 在微服务架构中,数据的高效存储与快速查询是至关重要的。Redis作为一个高性能的内存数据结构存储系统,不仅可以用作缓存、消息代理,还可以扩展为向量数据库,实现高效的相…...

shell脚本基础学习_总结篇(完结)
细致观看可以,访问shell脚本学习专栏,对应章节会有配图https://blog.csdn.net/2201_75446043/category_12833287.html?spm1001.2014.3001.5482 导语 一、shell脚本简介 1. 定义: 2. 主要特点: 3. shell脚本的基本结构 4. S…...
什么是 C++ 中的函数对象?它有什么特点?
在 C 中,函数对象(Function Object)是一种可调用对象,它允许像函数一样被调用,但实际上它可能并不是真正的函数。函数对象可以是以下几种类型之一: 普通函数: 一个普通的、定义在命名空间或类…...

css:项目
这是一个完整的网站制作的流程 美工会先制作一个原型图: 原型图写的不详细,就是体现一个网页大致的布局 然后美工再做一个psd样例图片 然后再交给程序员 项目 模块化开发:把代码的不同的样式封装起来,需要用到相同样式的标签就…...
macOS 开发环境配置与应用开发指南
macOS 开发环境配置与应用开发指南 macOS作为苹果公司推出的操作系统,因其稳定性、优雅的用户界面和强大的开发支持,已成为开发者和创意专业人士的首选平台之一。无论是开发iOS、macOS桌面应用,还是Web应用、跨平台程序,macOS都提…...

[A-19][V06]ARMv8/v9-内存虚拟化原理
ver0.2 [看前序文章有惊喜,关注W\X\G=Z+H=“浩瀚架构师”,可以解锁全部文章] 前言 前一篇文章,我们介绍了ARM内存的属性,算是一个小小的里程碑点,接下来我们会把注意力重新拉回虚拟化的赛道。我们从[V-05] 虚拟化基础-异常模型(Exception model)之后,花了很多笔墨介绍…...
registry 删除私有仓库镜像
原文链接:https://blog.csdn.net/yogima/article/details/122172744 如果需要彻底删除,只需进行register 磁盘删除镜像 彻底删除了,就可以到达彻底删除的目的。 如果只需要软删除,则只需进行通过API删除。 curl --header "Ac…...

UPLOAD LABS | UPLOAD LABS 靶场初识
关注这个靶场的其它相关笔记:UPLOAD LABS —— 靶场笔记合集-CSDN博客 0x01:UPLOAD LABS 靶场简介 UPLOAD LABS 靶场是一个专门用于学习文件上传漏洞攻击和防御的靶场。它提供了一系列文件上传漏洞的实验环境,用于帮助用户了解文件上传漏洞的…...

Samba服务器常见问题处理
指定的网络文件夹目前是以其他用户名和密码进行映射的。要用其他用户名和密码进行连接,首先请断开所有现有的连接到网络共享的映射 解决方案 单击“开始”菜单,选择“运行…”。 在弹出的窗口中,输入cmd 进入命令行模式,并输入…...

Java基础 设计模式——针对实习面试
目录 Java基础 设计模式单例模式工厂模式观察者模式策略模式装饰器模式其他设计模式 Java基础 设计模式 单例模式 单例模式(Singleton Pattern) 定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。适用场景&…...
最大公约数和最小公倍数-多语言
目录 C 语言实现 Python 实现 Java 实现 Js 实现 题目:输入两个正整数m和n,求其最大公约数和最小公倍数。 程序分析: 最小公倍数输入的两个数之积除于它们的最大公约数,关键是求出最大公约数; 求最大公约数用辗转…...
第三方数据库连接免费使用和安装
是强大的一体化数据库开发解决方案,可从单一应用程序无缝连接多个数据库,包括 MySQL、PostgreSQL、MongoDB、MariaDB、SQL Server、Oracle、SQLite 和 Redis。 下载:https://download.csdn.net/download/mo3408/90045937 升级特性 模型&…...

水库大坝安全监测之量水堰计应用
量水堰计是水库大坝安全监测系统中的一种关键设备,主要用于测量水库水位、流量等水力参数。以下是量水堰计在水库大坝安全监测中的应用及注意事项: 一、量水堰计的工作原理 量水堰计是一种专门用于测量水流流量的仪器,其工作原理主要基于水流…...

算法笔记:滑动窗口
前言 滑动窗口作为一个考点较高的算法,广泛应用于子串问题中,本文将进行详细讲解。 一、滑动窗口是什么 滑动窗口是双指针算法的一种,基本思路为维护一个窗口,然后从前往后遍历元素进行运算。 二、滑动窗口算法和其他双指针算…...

Ubuntu下的Graphviz的基础使用方法
一、Graphviz介绍 graphviz是贝尔实验室开发的一个开源的工具包,它使用一个特定的DSL(领域特定语言):dot作为脚本语言,然后使用布局引擎来解析此脚本,并完成自动布局 1、什么是Graphviz 官网地址,https://www.graphviz.org/ Gr…...

微积分复习笔记 Calculus Volume 1 - 6.8 Exponential Growth and Decay
6.8 Exponential Growth and Decay - Calculus Volume 1 | OpenStax...

React的ts文件中通过createElement拼接一段内容出来
比如接口返回一个值 const values [23.00, 40.00/kg];想做到如下效果, 如果单纯的用render渲染会很简单, 但是在ts文件中处理,所以采用了createElement拼接 代码如下: format: (values: string[]) > {if (!values || !val…...

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

Python双向链表、循环链表、栈
一、双向链表 1.作用 双向链表也叫双面链表。 对于单向链表而言。只能通过头节点或者第一个节点出发,单向的访问后继节点,每个节点只能记录其后继节点的信息(位置),不能向前遍历。 所以引入双向链表,双…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...
计算机系统结构复习-名词解释2
1.定向:在某条指令产生计算结果之前,其他指令并不真正立即需要该计算结果,如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方,那么就可以避免停顿。 2.多级存储层次:由若干个采用不同实现技术的存储…...