Java面试篇【JVM】常见面试题(2024最新)

JVM

1. Java内存区域详解

在这里插入图片描述
在这里插入图片描述
线程私有:程序计数器,虚拟机栈,本地方法栈
线程共享的:堆,方法区,直接内存

1.1 各个区域详解

程序计数器
每个线程需要一个计数器记录自己执行到哪一行了。线程之间切换需要保存自己的执行位置,因此必须每个线程有自己的计数器。
生命周期随着线程创建而创建,随着线程结束而死亡。

java虚拟机栈
由一个个栈帧组成,每个栈帧都拥有局部变量表,操作数栈,动态链接,方法出口等信息。
局部变量表存放了编译期可知的各种数据类型,对象引用。
可能出现两种错误,StackOverFlowError,OutofMemoryError
前者如果不允许虚拟机栈内存动态扩展,就可能因为递归导致栈深度超过当前java虚拟机最大深度的时候抛出异常。
后者是虚拟机栈内存大小可以动态扩展,如果虚拟机栈扩展着扩展着,没空间了,就会报错。

本地方法栈
很类似,但是执行的是本地方法。


存放对象实例,之前是所有对象都存放在堆中,现在有些新技术的产生,栈上分配,导致不是所有对象都在堆中了。
如果某些方法中的对象引用没有被返回或者没有被外面使用,没有逃逸出去,那就直接在栈上分配内存。
垃圾回收主要在堆区域。可细分为老年代和新生代。Eden,FromSurvivor,ToSurvivor。
在这里插入图片描述
对象一般在Eden中分配,经历一次GC之后,eden和S0中存活的,放到是s1种,下次就是,eden和s1中存活的,放到s0中,并且每次的GC存活,年龄+1。超过阈值就放入老年代中。

方法区
(现在已经不在永久代,而是在元空间)存储已经被虚拟机加载的类信息,常量,静态变量等等。
常用参数:

-XX:MetaspaceSize=N//元空间的初始大小
-XX:MaxMetaspaceSize=M//最大大小

2 虚拟机对象

2.1 对象的创建

在这里插入图片描述

  1. 类加载检查:遇到一条new指令,首先检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析、初始化过。如果没有就要先执行相应的类加载过程。
    加载过程如下图,下一章节详细说。
    在这里插入图片描述
  2. 分配内存:类加载通过以后,虚拟机为新生对象分配内存,对象所需要的内存大小在类加载完之后就确定了。
  3. 初始化零值:将分配的内存空间,都初始化为0值
  4. 设置对象头:对象头存放着对象的hashcode,元数据信息,GC分代年龄之类的。
  5. 执行init方法:此时从jvm的角度看,一个新的对象已经产生了,但是从java的角度看,所有字段都还是0.所以接着执行init方法,把对象按照程序员的意愿初始化,这样真正的对象才算产生出来。

2.2 类加载过程

在这里插入图片描述
加载

  1. 通过全类名获取类的二进制字节流。
  2. 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
  3. 内存中生成一个代表该类的Class对象,作为方法区这些数据的访问入口
    验证
    在这里插入图片描述
    准备
    正式为类变量分配内存并设置类变量初始值。这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在 Java 堆中。而类变量在方法区中。
    初始值通常为默认的0,0L,null,false等。public static int value = 11;实际上此时为0,final的话为11.

解析
虚拟机将常量池中的符号引用替换为直接引用的过程。解析动作主要针对类或者接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符七类符号引用进行。
符号引用;一组符号描述目标,可以是任何字面量。直接引用就是直接指向目标的指针、相对偏移量、句柄等等。
举例:jvm给每个类准备了一个方法表,存放类的所有方法。不同的方法肯定在表中偏移量不同,然后调用一个方法的时候,只要知道这个方法在表中的偏移量就可以直接调用。所以解析过程就是把原本的字面量的符号引用,替换为了直接引用。得到了类、字段、方法在内存中的指针或者偏移量。

初始化
类加载的最后一步,执行初始化方法clinit()的过程。
只有主动使用类才初始化类

1.遇到new、getstatic、putstatic、invokestatic这四条字节码指令时。
    即程序创建一个类的实例对象。
    程序访问类的静态变量。
    给类的静态变量赋值。
    调用类的静态方法。
    这些时候初始化,上文的public static int value = 11;会从0变成11
2.使用java.lang.reflect包的方法对类进行反射调用时,如Class.forName("...").newInstance()
    如果此时没有初始化,则需要初始化。
3.初始化一个类,如果父类还没初始化,则需要先初始化父类。如果实现了某个接口,这个接口有默认方法。接口要先初始化。
4.jvm启动时,用户需要定义一个要执行的主类,也就是包含main的那个类,虚拟机要先初始化。
5.轻量级反射啥啥的,看不懂。这个直接copy:
    MethodHandle和VarHandle可以看作是轻量级的反射调用机制,而要想使用这2个调用, 就必须先使用findStaticVarHandle来初始化要调用的类。

卸载

该类的class对象被GC
三个要求:
    1.该类的所有实例对象都已经被GC,堆中不存在该类的实例对象。
    2.该类没有在其他任何地方被引用。
    3.该类的类加载器的实例已经被GC。
在JVM生命周期类,jdk自带的BootstrapClassLoader,ExtClassLoader,AppClassLoader负责加载jdk提供的类,所以它们(类加载器的实例)肯定不会被回收,它们加载的类也不会被卸载。而我们自定义的类加载器的实例是可以被回收的,所以使用我们自定义加载器加载的类是可以被卸载掉的。

2.3 对象的内存布局

对象在内存中有三块区域:对象头,实例数据,对齐填充。
对象头:

  1. 用于存储对象自身的运行时数据(哈希码,GC分代年龄,锁状态标志等等)
  2. 类型指针,对象指向类的元数据的指针,通过这个指针确定这个对象是哪个类的实例。

实例数据:
程序中定义的各种类型的字段内容。
对其填充:
不必然存在,只是为了凑齐8字节的整数倍

3.JVM垃圾回收

在这里插入图片描述
MinorGC一直重复这个过程:eden+from区->to区。
to区填满之后,所有对象移步老年代。
在这里插入图片描述

3.1 GC分类

部分收集
新生代收集:MinorGC/YoungGC
老年代收集:MajorGC/OldGC
混合收集:MinorGC+部分老年带回收

整堆收集
FullGC

3.2 怎么判断对象已经死亡?

在这里插入图片描述
引用计数法
有地方引用它,就+1,引用失效就减1.但是很难解决循环引用的问题。一般不使用这种。

可达性分析
在这里插入图片描述
GCRoot对象

  1. 比如虚拟机栈中引用的对象
  2. 本地方法栈中引用的对象
  3. 方法区静态属性、静态常量引用的对象
  4. 所有被同步锁持有的对象

3.3 垃圾收集算法

  1. 标记清除
  2. 复制算法
  3. 标记整理
  4. 分代收集
    标记清除 产生大量碎片
    在这里插入图片描述
    标记复制 空间只能使用一半
    在这里插入图片描述
    标记整理 需要大量移动
    在这里插入图片描述
    分代收集
    新生代:主要采用复制算法,但是不是分为两块。而是eden+from->to
    老年代:标记清除/标记整理。

3.4 类文件结构

在这里插入图片描述

  1. 访问标志:是不是public的?是不是abstract的?是不是final的?是不是enum的?是不是接口?
  2. 索引信息:当前类、父类、接口数量、接口信息
  3. 字段表集合:描述类中声明的变量,包括静态变量和实例变量,不包括方法的局部变量。
  4. 方法表集合:描述类声明的方法。
  5. 属性表集合:上述表运用到的信息。

3.5 类加载方式

所有的类都由类加载器加载,加载的作用就是将 .class文件加载到内存。
JVM内置三个classLoader:

  1. BootstrapClassLoader:加载javahome/lib目录下的jar包
  2. ExtentionClassLoader: 加载jrehome/lib/ext 下的jar包,或者被java.ext.dirs系统变量指定的路径下的jar包
  3. AppClassloader:面向用户的加载器,加载当前应用classpath下的jar包和类

双亲委派模型
在这里插入图片描述
好处:保证了java程序的稳定运行。避免类的重复加载,也保证了java的核心API不被篡改。

3.6 JVM常用参数设置

Xms2G -Xmx5G //最小2G最大5GB的堆内存大小。
-XX:NewSize=256m //为新生代分配最小256m的内存
-XX:MaxNewSize=1024m//最大1024M的新生代内存
-Xmn256m//新生代分配256m的内存,最小最大一致的讲话写法
-XX:NewRatio=1 // 新生代与老年代1:1
-XX:MetaspaceSize=N //元空间的初始大小
-XX:MaxMetaspaceSize=M //元空间的最大大小
-XX:=UseSerialGC //使用SerialGC
-XX:+UseParallelGC
-XX:+USeParNewGC
-XX:+UseG1GC

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LVS集群---二

1.LVS工作模式和相关命令 1.1LVS集群工作模式 - lvs-nat:修改请求报文的目标IP,多目标IP的DNAT- lvs-dr:操纵封装新的MAC地址(直接路由)- lvs-tun:隧道模式 1.1.1 LVS的NAT模式 lvs-nat:本质是多目标IP的…

flutter 使用webview

背景: 一般都有使用webview加载网页的需求,比如加载隐私协议、用户协议等。 如何做: 当然,我们自己不用封装轮子,在pub.dev上有成熟的轮子:webview_flutter 首先,将依赖导入,在pub…

MooC下载pdf转为ppt后去除水印方法

1、从MooC下载的课件(一般为pdf文件)可能带有水印,如下图所示: 2、将pdf版课件转为ppt后,同样带有水印,如下图所示: 3、传统从pdf中去除水印方法不通用,未找到有效去除课件pdf方法…

c语言指针基础(中)

指针 assert断言 要想使用assert需要包含头文件<assert.h>&#xff0c;作用是程序在运行时要确定符合某种条件,如果符合程序正常运行,如果不符合,就会报错,停止运行。 例子: int *p; assert(p!NULL)程序运行到assert这条语句时,会判断p是不是空指针,如果不是空指针程序…

LVS 负载均衡 - DR模式

一 . DR 模式 直接路由 1.介绍&#xff1a; 直接路由&#xff08;Direct Routing&#xff09;&#xff1a;简称 DR 模式&#xff0c;采用半开放式的网络结构&#xff0c;与 TUN 模式的结构类似&#xff0c;但各节点并不是分散在各地&#xff0c;而是与调度器位于同一个物…

曲线曲面 - 连续性, 坐标变换矩阵

连续性 有两种&#xff1a;参数连续性&#xff08;Parametric Continuity&#xff09;、几何连续性&#xff08;Geometric Continuity&#xff09;参数连续性&#xff1a; 零阶参数连续性&#xff0c;记为&#xff0c;指相邻两段曲线在结合点处具有相同的坐标 一阶参数连续性&…

css-通用样式按钮加号

1.实现 2.代码 html <div class"addF">&#xff0b;</div> css .addF{width:40px;font-size:25px;font-weight:600;background-color:rgb(64, 158, 255);text-align:center;color:white;height:34px;border-radius:3px;line-height:34px; }

Windows下 OracleXE_21 数据库的下载与安装

Oracle 数据库的下载与安装 数据库安装包下载数据库安装访问数据库进行测试Navicat连接数据库 1. 数据库安装包的下载 1.1 下载地址 Oracle Database Express Edition | Oracle 中国 1.2 点击“下载 Oracle Database XE”按钮&#xff0c;进去到下载页面&#xff08;选择对…

ES基础-ES优化

优化-硬件选择 Elasticsearch 的基础是 Lucene&#xff0c;所有的索引和文档数据是存储在本地的磁盘中 磁盘在现代服务器上通常都是瓶颈。Elasticsearch重度使用磁盘&#xff0c;你的磁盘能处理的吞吐量越大&#xff0c;你的节点就越稳定。这里有一些优化磁盘I/O的技巧&#x…

数据处理分类、数据仓库产生原因

个人看书学习心得及日常复习思考记录&#xff0c;个人随笔。 数据处理分类 操作型数据处理&#xff08;基础&#xff09; 操作型数据处理主要完成数据的收集、整理、存储、查询和增删改操作等&#xff0c;主要由一般工作人员和基层管理人员完成。 联机事务处理系统&#xff…

ELF 1技术贴|在NXP源码基础上适配开发板的按键功能

本次源代码适配是在NXP i.MX6ULL EVK评估板的Linux内核源代码&#xff08;特定版本号为Linux-imx_4.1.15&#xff09;的基础中展开的。 首要任务集中在对功能接口引脚配置的精细调整&#xff0c;确保其能无缝匹配至ELF 1开发板。接下来&#xff0c;我们将详细阐述适配过程中关…

Maven对项目构建过程中的每个步骤的详细介绍

1. 概述 Maven除了管理项目的依赖以外&#xff0c;还能对项目的构建过程进行管理。除了使用命令行以外&#xff0c;我们平时经常用IDEA图形化界面进行操作&#xff0c;如图所示&#xff1a; 本文将详细描述Maven对项目构建过程中的每一个阶段。 2. 构建过程 注意&#xff1…

垂直分表、分布式Id详细介绍、模板引擎FreeMarker、对象存储服务MinIO(黑马头条Day02)

目录 垂直分表 分布式ID 为什么需要分布式ID 分布式ID需要满足的条件 常见的分布式ID算法有哪些 项目中具体如何使用分布式ID 模板引擎FreeMarker freemarker简介 对象存储服务MinIO MinIO简介 MinIO的优点 本项目中使用的FreeMarker和MinIO示例 今天在学习黑马头…

短视频矩阵系统技术开发商--支持技术资质核验(自研独立saas框架开发)

短视频矩阵系统是一种能够帮助用户快速制作、发布和推广短视频的系统。 &#x1f347;&#x1f347;它通常包括以下部分&#xff1a; 短视频矩阵系统#短视频矩阵系统源头#短视频矩阵系统源头开发#短视频矩阵系统软件#短视频矩阵系统技术#2024互联网风口项目短视频矩阵系统带动…

ORACLE RAC反应卡顿时enq: SV - contention和latch: row cache objects的分析

某客户数据库系统使用ORACLE RAC 11G版本&#xff0c;两个节点。在上午8点钟之后&#xff0c;业务开始大量进行时&#xff0c;出现严重的卡顿问题&#xff1b;在工程师分析后&#xff0c;发现当时出现了很多异常等待数据&#xff0c;如典型的enq: SV - contention 、enq: TX - …

【Java JVM】Class 文件

Java 的口号 “一次编写, 到处运行 (Write Once, Run Anywhere)” 的基础: JVM 和 所有平台都统一支持的程序存储格式 – 字节码 (Byte Code)。 只要在对应的平台安装对应的 JVM, 将我们编写的源码编译为 Class 文件, 就能达到了一次编写, 导出运行的目标, 中间的所有细节由不同…

微服务基础

目录 一、单体架构 二、分布式架构 三、微服务 四、微服务结构 五、SpringCloud 六、服务拆分 七、远程调用 一、单体架构 单体架构就是将业务的所有功能都集中在一个项目中进行开发&#xff0c;并打成一个包进行部署。 他的优点很明显&#xff0c;就是架构简单&#xff…

微信小程序(五十二)开屏页面效果

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.使用控件模拟开屏界面 2.倒计时逻辑 3.布局方法 4.TabBar隐藏复现 源码&#xff1a; components/openPage/openPage.wxml <view class"openPage-box"><image src"{{imagePath}}"…

单细胞联合BulkRNA分析思路|加个MR锦上添花,增强验证~

今天给大家分享一篇IF7.3的单细胞MR的文章&#xff0c;2023年12月发表在Frontiers in Immunology&#xff1a;An integrative analysis of single-cell and bulk transcriptome and bidirectional mendelian randomization analysis identified C1Q as a novel stimulated risk…

力扣刷题Days11第二题--141. 环形链表(js)

目录 1,题目 2&#xff0c;代码 2.1快慢指针 2.2&#xff0c;哈希表 3&#xff0c;学习与总结 3.1自己尝试写快慢指针 反思 1,题目 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&…