关于JVM常见的十道面试题

方法区、永久代和元空间有什么区别?

方法区、永久区和元空间是Java虚拟机用于存储类信息的区域,它们在不同的Java虚拟机版本有所不同:

  1. 方法区:方法去是一块用于存储类的结构信息、常量、静态变量、即时编译器编译后的代码等数据的内存区域。在早期的Java虚拟机版本中,方法区被永久实现为永久代。但是在Java 8及其以后版本中,方法去被移除,取而代之的是元空间
  2. 永久代:永久代是Java虚拟机中的一个特定的方法区,用于存储类的元数据新消息,如类名、方法名、字段名等。永久代的大小是固定的,并且在默认的情况下比较小。由于永久代的大小是有限的,当加载的类过多或者动态生成的类过多的时候,就容易出现永久代溢出的情况
  3. 元空间:元空间是Java 8及其以后版本中取代永久代的新方法区实现。元空间并不在虚拟机内存中,而是使用本地内存来存储类的元数据信息。元空间的大小可以根据需要进行调整,并且默认的情况下是不限制大小的。元空间的好处是可以避免永久代的溢出问题,并且可以更好的利用系统资源

所以说,方法区是一个规范层面的概念,而永久代是早期 HotSpot JVM(JVM的实现) 对方法区的具体实现方式,现已废弃;而元空间则是后来 HotSpot 为了改进内存管理,和解决永久代带来的内存溢出问题所采用的新的实现机制

为什么要使用元空间替代永久代?元空间有什么优点?

  • 降低内存溢出:当使用永久代实现方法区时,永久代的最大容量受制于 PermSize 和 MaxPermSize 参数设置的大小,而这两个参数的大小又很难确定,因为在程序运行时需要加载多少类是很难估算的,如果这两个参数设置的过小就会频繁的触发FullGC 和导致 OOM(Out of Memory,内存溢出)。但是,当使用元空间替代了永久代之后,出现 00M 的几率就被大大降低了,因为元空间使用的是本地内存,这样元空间的大小就只和本地内存的大小有关了,从而大大降低了OOM 的问题
  • 降低运维成本:因为元空间使用的是本地内存,这样就无需运维人员再去专门设置和调整元空间的大小了

常量池和字符串常量池有什么区别?字符串常量池是如何实现的?

常量池和自负床常量池都是Java中用于优化性能和内存使用的机制,但是它们的应用场景和存储内容有所不同:

常量池:是指存储在.class文件中的一组常量的集合,包括字符串常量、数字常量、类和接口的名称以及其他一些常量。常量池是Java中的一种优化机制,用于避免重复存储相同的常量值,从而减小类文件的大小

字符串常量池:也是常量池中的一种,专门用于存储字符串常量的

二者区别如下:

  1. JDK 1.8之后,字符串常量池存储在堆上,而常量池在元空间本地内存中
  2. 常量池包含很多的内容,如类、方法、字段你等常量都是存储在常量池中,而字符串常量池只是用于存储字符串常量对象

字符串常量池的实现

自负床常量池是由C++中的HashMap实现的,它的key是字符串的字面量,value是字符串对象的引用

什么叫做堆溢出?实际工作中哪些情况会导致堆溢出?

堆溢出通常是指堆内存中的对象过多,无法被垃圾回收导致的内存溢出出错。以下是常见的导致堆溢出的场景和原因:

  1. 内存泄露:最常见的情况就是内存泄漏,即对象被创建后不再被使用,但是没有被释放。这会导致之堆中的对象数量逐渐增加,直到堆溢出。例如ThreadLocal使用不当,使用完成之后未调用remove方法导致内存泄漏,以及忘记释放各种连接,也会导致内存泄漏,如数据库连接、网络连接和IO连接等
  2. 无限递归创建大量对象:无限递归调用一个方法可能会导致栈溢出,但是如果当调用中创建了大量对象并持续递归,也可能导致堆溢出
  3. 创建大量的大对象:创建大量大对象,尤其是数组或集合,可能导致堆溢出。如果没有足够的连续内存来存储大对象,堆溢出会发生
  4. 未合理设置堆大小:如果未合理设置 Java 虚拟机的堆大小参数(如 -Xmx 和 -Xms),可能导致堆溢出
  5. Excel 导入和导出:如果有大的 excel 要进行导入和导出的情况下,因为其操作都是在内存中拼接和组织数据的,如果 excel过大,很容易就会造成堆溢出

什么叫做栈溢出?导致栈溢出的原因是啥?

栈溢出是指在程序运行的时候,当栈空间中可用内存大小被超出所能容纳的大小的时候,导致发成异常或错误。以下是常见的导致栈溢出的场景和原因:

  1. 递归调用:在递归算法中,如果递归的深度过大,每次递归都会在栈上生成一个函数调用的帧,当栈空间内不足以容纳这些帧的时候,就会发生栈溢出
  2. 无限递归:在某些情况下,由于代码逻辑错误或循环调用,可能会导致无限递归的情况发生,从而导致栈溢出
  3. 大规模数据结构使用:当使用大规模的数据结构(如大数组、大集合等)时,如果栈空间不足以容纳这些数据,就会导致栈溢出。解决方法时尽量使用堆空间存储的答案规模数据结构,或者增加栈的大小
  4. 深度嵌套函数调用:当函数调用过于深度嵌套的时候,每次调用都会在栈中生成一个新的函数帧,如果嵌套层过多,就会导致栈溢出

说一下类加载机制?Loading和Class Loading有什么区别?

类加载机制是Java虚拟机在运行Java程序的时候用来加载文件的过程。类加载机制包括以下几个步骤:

  1. 加载:将类的字节码文件加载到内存中,并创建一个对应的Class对象,用这个来表示类。加载阶段是通过类加载器来实现的
  2. 验证:确保加载的类文件符合Java虚拟机的规范不会造成安全问题
  3. 准备:为类的静态变量分配内存,并初始化为默认值
  4. 解析:解析阶段是JVM将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程。这个过程会涉及到三个概念:
    1. 符号引用:类文件中的一个抽象引用方式,它并不涉及具体的内存地址或者对象实例。符号引用包括三方面的信息:类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。这些信息足以唯一的确定一个类、字段或者方法,但是类被加载到JVM之前,并没有实际的内存布局关联
    2. 直接引用:一种可以直接指向目标对象、类、字或者方法在JVM内存中的物理位置的引用方式。例如:指针、偏移量等。一但是有了直接引用,就可以直接访问目标实体,而无需经过其他的查找过程
    3. 替换过程:当JVM解析阶段需要对某个符号进行解析的时候,会根据类加载的结果生成对应的直接引用。比如,当一个类引用了另一个类的方法或者字段的时候,解析阶段会确保被引用的目标类已经被加载,并会计算出被饮用方法或字段在内存中的准确位置,然后用这个位置信息替换掉原来的符号引用
  5. 初始化:执行类初始化代码,包括静态变量的复制和静态代码块的执行。初始化阶段是类加载的最后一步

什么是双亲委派模型?为什么要用双亲委派模型?

双亲委派模型是Java类加载机制的一种设计模式,用于保证类加载的安全性和一致性。在双亲为欸配模型中,类加载器在尝试加载一个类时,会先将加载的请求派给其父类加载器,如果父类加载器无法加载该类(即父类加载器的搜索范围内找不到对应的类),则子类加载器才会尝试加载

自 JDK 1.2 以来,Java 一直保持着三层类加载器、双亲委派的类加载架构器,如下图所示: 

  • 启动类加载器:加载 JDK 中 lib 目录中 Java 的核心类库,即 $JAVA_HOME/lib 目录。
  • 扩展类加载器:加载 lib/ext 目录下的类
  • 应用程序类加载器:加载我们写的应用程序
  • 自定义类加载器:根据自己的需求定制类加载器

双亲委派模型的主要目的就是确保Java类的安全性和一致性,具体的表现在以下几个方面:

  1. 防止重复加载:比如A类和B类都有一个父类C类,那么当A启动的时候就会将C类加载起来,那么在B类加载的时候就不需要进行重复加载C类
  2. 更安全:使用双亲委派模型也可以保证Java的核心API不会被串改,如果没有使用双亲委派模型,而是每个类加载自己的话就会出现一点问题,比如我们编写一个称为java.lang.Object类的话,那么程序运行的时候,系统就会出现多个不同的Object类,而有些Object类又是用户自己提供的因此安全性就不能得到保证

有哪些打破双亲委派模型的场景?为什么要打破双亲委派模型?

打破双亲委派模型的主要场景主要是以下两种:

  1. Java中自带的SPI机制
  2. Tomcat

SPI机制:SPI是JDK内置的一种服务提供发现机制。例如,数据库驱动就是SPI的典型实现。在Java中,数据库驱动就是一个典型的SPI使用场景。不同的数据库厂商都提供了自己的数据库驱动实现,这些实现都是实现了同一个JDBC接口。JVM在运行时可以动态加载适合的数据库驱动,使得开发者可以在不修改代码的情况下切换不同的数据库

双亲委派模型是从下往上加载,而 SPI机制是从上往下加载

Tomcat:Tomcat 也要打破了双亲委派模型,因为一个外置 Tomcat 中要部署多个应用,多个 Web 应用程序在同一个omcat 实例中独立运行,而不会相互干扰或导致类冲突,所以 Tomcat 需要打破双亲委派模型来实现类隔离、热部署和解决类库版本冲突等问题

  1. 类隔离:应用服务器通常需要在同一JVM 中运行多个不同的 Web 应用程序,每个应用程序都可能依赖于不同版本的类库。为了保持这些应用程序的隔离性,Tomcat 需要使用自定义的类加载器来加载各个 Web 应用程序的类。这样可以确保每个 Web 应用程序都不会干扰其他应用程序的类加载
  2. 热部署和热加载:Tomcat 支持热部署和热加载,允许在应用程序运行时替换类文件而不需要重新启动整个应用服务器。为了实现这一功能,Tomcat 需要自己的类加载器,以便能够动态加载新的类定义
  3. 类库版本冲突:有时 Web 应用程序需要使用自己的类库版本,而不是应用服务器提供的全局类库版本。这可能会导致类库版本冲突,为了解决这个问题,Tomcat 可以使用自定义的类加载器来加载应用程序的类,而不受全局类库的影响

判断死亡对象的算法有哪些?

判断对象是否存活的常见算法主要有以下两种:

  1. 引用计数算法
  2. 可达性分析算法

引用计数算法

引用计数器的实现思路是,给对象增加一个引用计数器,没达昂有一个地方引用它时,计数器就+1;当引用失效的时,计数器就-1;任何时刻计数器为0的对象就是不能再被使用的,即对象已死

优点:实现简单,判定效率比较高

缺点:引用计数无法解决对象循环引用的问题

可达性分析算法

可达性分析算法是通过一系列为GC Roots的对象作为起点,从这些接电脑开始向下搜索搜索走过的路径称为引用链,达昂一个对象到GC Roots没有任何的引用链相连时(从GC Roots 到这个对象不可达)时,证明此对象是不可用的,也就是死亡对象

对象 Object5-0bject7 之间虽然彼此还有关联,但是它们到 GC Roots 是不可达的,因此它们会被判定为可回收对象

目前主流的Java虚拟机都是使用可达性分析算法来判断死亡对象的

什么对象可以作为GC Roots?为什么它们能作为GC Roots?

在Java中,可作为GC Roots的对象有以下几种:

  1. Java虚拟机栈(栈帧中的本地变量表)中引用的对象
  2. 本地方法栈中(Native方法)引用的对象
  3. 方法区中的类静态属性引用的对象
  4. 方法区中常量引用的对象

其中,Java 虚拟机栈和本地方法栈中的引用对象,是目前线程正在执行时用的对象,所以它们不能被回收,因此它们可以作为 GC Roots。而方法区中的静态属性和常量对象与类本身相关联,而类已经被加载到程序中了,所以类属于系统的一部分了,因此类所关联的静态属性和常量也就是系统的一部分了,所以它们可以作为 GC Roots

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

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

相关文章

Facebook群控:利用IP代理提高聊单效率

在当今社交媒体竞争激烈的环境中,Facebook已经成为广告营销和推广的重要平台,为了更好地利用Facebook进行推广活动,群控技术应运而生。 本文将深入探讨Facebook群控的定义、作用以及如何利用IP代理来提升群控效率,为你提供全面的…

C语言问题汇总

指针 #include <stdio.h>int main(void){int a[4] {1,2,3,4};int *p &a1;int *p1 a1;printf("%#x,%#x",p[-1],*p1);} 以上代码中存在错误。 int *p &a1; 错误1&#xff1a;取a数组的地址&#xff0c;然后1&#xff0c;即指针跳过int [4]大小的字节…

【动态规划】【树形dp】【C++算法】968监控二叉树

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode:968监控二叉树 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所…

web前端--------渐变和过渡

线性渐变&#xff0c;是指颜色沿一条直线进行渐变&#xff0c;例如从上到下、从左到右。 当然&#xff0c;CSS中也支持使用角度来设置渐变的方向&#xff0c;角度单位为deg。 0deg&#xff0c;为12点钟方向&#xff0c;表示从下到上渐变。 90deg&#xff0c;为3点钟方向&…

Llama2大模型开源,大模型的Android时代来了?

就昨天凌晨,微软和Meta宣布Llama2大模型开源且进一步放开商用,一下朋友圈刷屏。要知道,开源界最强大的模型就是过去Meta开源的Llama,而现在Llama2更强大,又开放商用,更有微软大模型霸主企业撑腰(微软既投资大模型界的IOS——ChatGPT,又联合发布大模型的Android——Llam…

【Django】Cookie和Session的使用

Cookies和Session 1. 会话 从打开浏览器访问一个网站&#xff0c;到关闭浏览器结束此次访问&#xff0c;称之为一次会话。 HTTP协议是无状态的&#xff0c;导致会话状态难以保持。 Cookies和Session就是为了保持会话状态而诞生的两个存储技术。 2. Cookies 2.1 Cookies定…

Git使用命令大全

命令大全参考阮一峰的博客&#xff0c;根据自己的使用习惯作了调整。 Git常用命令 其他常用的命令 配置Git # 显示当前的Git配置 $ git config --list# 编辑Git配置文件 $ git config -e [--global]# 设置提交代码时的用户信息 $ git config [--global] user.name "[nam…

【Simulink系列】——动态系统仿真 之 离散系统线性离散系统

一、离散系统定义 离散系统是指系统的输入与输出仅在离散的时间上取值&#xff0c;而且离散的时间具有相同的时间间隔。满足下列条件&#xff1a; ①系统&#xff08;的输入输出&#xff09;每隔固定时间间隔才更新一次。固定时间间隔称为采样时间。 ②系统的输出依赖当前的…

C++拷贝构造函数、赋值运算符重载

1.拷贝构造函数 拷贝构造函数的写法如图所示 调用方式如下 接下来我来说说它的特征 1.1特征 拷贝构造函数&#xff1a;只有单个形参&#xff0c;该形参是对本类类型对象的引用(一般常用const修饰)&#xff0c;在用已存在的类类型对象创建新对象时由编译器自动调用。 拷贝构造函…

debian12 解决 github 访问难的问题

可以在 /etc/hosts 文件中添加几个域名与IP对应关系&#xff0c;从而提高 github.com 的访问速度。 据搜索了解&#xff08;不太确定&#xff09;&#xff0c;可以添加这几个域名&#xff1a;github.com&#xff0c;github.global.ssl.fastly.net&#xff0c;github.global.fa…

电脑显示mfc140u.dll丢失怎么修复,这几个方法都可以解决

当打开软件时出现"mfc140u.dll丢失"的错误提示&#xff0c;通常是由于缺少或损坏了Microsoft Foundation Class (MFC)库文件导致的。MFC是Microsoft提供的一套用于开发Windows应用程序的类库&#xff0c;它包含了许多常用的功能和组件。 1、以下是可能导致"mfc…

Leetcode—33. 搜索旋转排序数组【中等】

2024每日刷题&#xff08;110&#xff09; Leetcode—33. 搜索旋转排序数组 实现代码 class Solution { public:int search(vector<int>& nums, int target) {int n nums.size();int l 0, r n - 1;while(l < r) {int m l (r - l) / 2;if(nums[m] target) …

面试数据结构与算法总结分类+leetcode目录【基础版】

&#x1f9e1;&#x1f9e1;&#x1f9e1;算法题目总结&#xff1a; 这里为大家总结数据结构与算法的题库目录&#xff0c;如果已经解释过的题目会标注链接更新&#xff0c;方便查看。 数据结构概览 Array & String 大家对这两类肯定比较清楚的&#xff0c;同时这也是面试…

BUUCTF-Real-[Flask]SSTI

目录 漏洞描述 模板注入漏洞如何产生&#xff1f; 漏洞检测 漏洞利用 get flag ​编辑 漏洞描述 Flask框架&#xff08;jinja2&#xff09;服务端模板注入漏洞分析&#xff08;SSTI&#xff09; Flask 是一个 web 框架。也就是说 Flask 为您提供工具、库和技术来允许您构…

【Tomcat与网络9】提高Tomcat启动速度的八大措施

本文我们来看一下如何对Tomcat进行调优&#xff0c;我们对于Tomcat的调优主要集中在三个方面&#xff1a;提高启动速度、提高系统稳定性和提高并发能力&#xff0c;后两者很多时候是相辅相成的&#xff0c;我们放在一起看。 Tomcat现在一般都嵌入在SpringBoot里&#xff0c;因…

2、安全开发-Python-Socket编程端口探针域名爆破反弹Shell编码免杀

用途&#xff1a;个人学习笔记&#xff0c;欢迎指正&#xff01; 目录 主要内容&#xff1a; 一、端口扫描(未开防火墙情况) 1、Python关键代码: 2、完整代码&#xff1a;多线程配合Queue进行全端口扫描 二、子域名扫描 三、客户端&#xff0c;服务端Socket编程通信cmd命…

汽车租赁系统

目录 一.研究背景 二.系统架构 1、SSM 2、JAVA 3、MySQL 4、系统架构 三.系统功能 1、车辆管理 2、客户管理 3、销售管理 4、统计分析 四.系统实现 五.结论总结 一.研究背景 传统的销售与信息统计管理都主要依靠人工&#xff0c;处理出的销售数据量与使用管理系统…

jmeter-03界面介绍

文章目录 主界面介绍工具栏介绍测试计划介绍线程组介绍线程组——选择测试计划&#xff0c;右键-->添加-->线程-->线程组1.线程数2.准备时长(Ramp-up)3.循环次数4.same user on each iteratio5.调度器 主界面介绍 工具栏介绍 新建测试计划&#xff1a;创建一个空白的测…

外包干了10个月,技术退步明显...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

【数据分享】1929-2023年全球站点的逐日最高气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01; 之前我们分享过1929-2023年全球气象站…