JVM面试题与答案

JVM内存布局

JVM在内存布局上可以分为哪些区域?

  • 堆(线程共享):GC的主要回收地,包含几乎所有的实例对象、字符串常量池;
  • 元空间(线程共享):在本地内存分配,包含类元信息、字段、静态属性、方法、常量等;
  • 虚拟机栈(线程私有):是描述Java方法执行的内存区域;
  • 本地方法栈(线程私有):本地方法栈为Native方法服务,线程调用本地方法时,会进入一个不再受JVM约束的世界;
  • 程序计数器(线程私有):程序计数器用来存放执行指令的偏移量和行号指示器等,线程执行或恢复都要依赖程序计数器。

垃圾回收

什么样的对象会被回收?

  • 通过一系列称为GC Roots 的对象作为起始点,从这些节点开始向下搜索,搜索所走的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,该对象将被回收,这个过程又称为可达性分析算法。
  • 简单来说就是,没有被GC Roots引用的对象会被回收。

什么是GC Roots?

  • 类静态属性或常量中引用的对象;
  • 虚拟机栈中引用的对象;
  • 本地方法栈中引用的对象。

什么是Stop The World?

  • 可达性分析的执行需要一个确保一致性的快照下进行,即对象引用关系达到稳定,因此必须停顿所有java线程,这种操作称为Stop The World,简称 STW。

什么是安全点和安全区域?

  • Stop The World 需要java线程到达安全点或安全区域后执行;
  • 安全点(Safe Point)可以是方法调用、循环跳转、异常跳转等;
  • 安全区域指一段代码片段中,引用关系不会发生变化。

被GC Roots引用的对象就一定不会回收吗?

  • 不一定
    • 强引用:始终不会被回收;
    • 软引用:会在OOM前被回收;
    • 弱引用:会在下一次YGC被回收;
    • 虚引用:无法通过该引用指向对象,为一个对象设置虚引用的唯一目的就是希望能在这个对象被回收时收到一个系统通知。

常见的GC回收算法有哪些?

  • 复制算法:将内存分为大小相等的两块,每次只使用其中一块,回收完把存活的复制到另一块,当前区域清空,这样回收的效率会很高,不会产生空间碎片,缺点是内存的使用上限变低了,而且不适合存放长期生存的对象,适合新生代;
  • 标记-清除:先根据GC Roots标记可达对象,再清除不可达的对象,缺点是回收的效率比复制算法低,回收完会产生内存空间碎片;
  • 标记-整理:在标记清除基础上增加了对象整理过程,避免空间碎片,适合老年代使用。

一个对象从出生到被回收的过程是什么?

  • 绝大部分对象在Eden区生成,当Eden区满了的时候,会触发YGC。没有被引用的对象直接回收,依然存活的对象被移送到Survivor区。
  • Survivor区分为S0和S1两块内存空间,每次YGC时,它们将存活的对象复制到未使用的那块空间,然后将当前正在使用的空间完全清除,交换两块空间的使用状态。另外每次GC后,存活的对象年龄会+1,当达到一个阈值的时候直接移至老年代,这个阈值默认是15。
  • 如果YGC要移送的对象大于Survivor区容量的上限,则直接移至老年代。如果老年代也无法放下,则会触发FGC。如果依然无法放下,则抛出OOM。

CMS的工作原理是什么?

  • cms的特点
    • 针对老年代;
    • 采用标记清除算法(为了节省时间,不进行整理,会产生内存碎片,可配置成周期性整理);
    • 并发收集,低停顿;
    • 以获得最短停顿时间为目标。
  • 回收过程
    • 初始标记:仅标记一下GC Roots能直接关联到的对象,不用向下追溯,速度很快,但需要STW;
    • 并发标记:进行GC Roots Tracing的过程, 这个过程相对耗时,但却可以和用户线程并行;
    • 重新标记:将并发标记期间发生变化的对象进行重新标记,需要STW;
    • 并发清除:回收所有的垃圾对象,整个过程中耗时最长的并发标记和并发清除都可以与用户线程一起工作。

G1的工作原理是什么?

  • g1的特点
    • 并行与并发:STW时间短。
    • 分代收集,收集范围包括新生代和老年代 ,而不需要与其他收集器搭配。将整个堆划分为多个大小相等的独立区域(Region),新生代和老年代不再是物理隔离,它们都是一部分Region的集合。
    • 结合多种垃圾收集算法,空间整合,不产生碎片。从整体看,是基于标记-整理算法,从局部(两个Region间)看,是基于复制算法。
    • 可局部收集,可预测停顿:每个Region都一个Remembered Set,记录引用其它区域对象的指针,这样便可以局部回收避免全局扫描。因此可以做到可预测停顿的时间。
    • 垃圾最多的Region,会被优先收集,这也是 G1 名字的由来。
  • 回收过程
    • 初始标记:仅标记一下GC Roots能直接关联到的对象,用户程序能在正确可用的Region中创建新对象。需要STW,但速度很快。
    • 并发标记:进行GC Roots Tracing的过程, 这个过程相对耗时,但却可以和用户线程并行;
    • 最终标记:将并发标记期间发生变化的对象进行重新标记,需要STW;
    • 筛选回收:首先排序各个Region的回收价值和成本,然后根据用户期望的GC停顿时间来制定回收计划,最后按计划回收一些价值高的Region中垃圾对象。 回收时采用复制算法,从一个或多个Region复制存活对象到堆上的另一个空的Region,并且在此过程中压缩和释放内存。可以并发进行,降低停顿时间,并增加吞吐量。

什么时候才应该考虑使用G1?

  • 堆空间在6G以上;
  • 存活数据占50%以上堆内存;
  • 大对象比较多或晋升比较快的情况;
  • GC 停顿在0.5~1s之间。

是否听说过ZGC?

  • ZGC是JDK11新加入的低延迟收集器,它立下了三个令人期待的flag:
    • 停顿时间不会超过 10ms;
    • 停顿时间不会随着堆的增大而增大(不管多大的堆都能保持在 10ms 以下);
    • 可支持几百 M,甚至几 T 的堆大小(最大支持 4T)。

常用命令与参数

如何查看jvm进程参数?

jinfo -flags 1280

如何查看gc回收情况?

##1280是pid,每1000ms 打印一次 
jstat -gcutil 1280 1000

如何导出dump文件?

jmap -dump:format=b,file=/usr/temp/heap.hprof 1280

CPU飙升如何定位问题?

## 找到占用cpu最多的进程,记录pid 
top 
## -Hp参数查看进程中占用cpu最多的线程信息,记录tid 
top -Hp 7083 
## 将十进制的tid转换成十六进制 
printf %x 32468 
## jstack将进程的线程栈信息打印,最后再根据十六进制tid找到问题线程的上下文 
jstack 7083 >stack.log

free命令的作用是什么?

  • 用于查看当前内存使用情况,主要包括的字段有total、used、free、shared、buff/cache、available;
  • available(可用内存)= free + buffer/cache - 不可被回收内存。

netstat命令的作用是什么?

  • 用于查看当前的网络信息汇总;
# 查看8081端口的使用情况 
netstat -tunpl | grep 8081

iostat命令的作用是什么?

  • 用于对磁盘IO进行监控:iostat -x(显示扩展报告);
  • 重点关注:
    • await字段:IO响应时间,一般小于5ms;
    • %util:显示了IO设备的繁忙程度,100%表示满负荷运行;

常用的JVM参数与推荐值

https://hujinyang.blog.csdn.net/article/details/103655911

类加载原理

一个类被加载的全流程是怎样的?

  1. 基于双亲委派模型,确定class的classloader;
  2. 执行具体的加载、验证、准备、解析、初始化等步骤。

什么是双亲委派模型?工作流程是什么?有什么优点?

img

  • 是一种递归上级优先加载的工作模型;
  • 工作过程:
  1. 当Application ClassLoader 收到一个未知类的加载请求时,会执行loadClass方法,先判断这个类是否已经被加载过,如果没有,则交给它的parent(Extension ClassLoader)进行加载;
  2. Extension ClassLoader收到类加载请求后,同样执行loadClass的逻辑,如果这个类没有被加载过,它会继续向它的上级Bootstrap ClassLoader询问这个类是否被加载;
  3. Bootstrap ClassLoader收到类加载请求后,如果发现该类没有被加载过,此时它会尝试加载这个类;
  4. 如果Bootstrap ClassLoader加载失败(在<JAVA_HOME>\lib中未找到所需类),会抛出异常,下级Extension ClassLoader捕获异常后,自己尝试加载;
  5. 如果Extension ClassLoader也加载失败,与上面过程同理,由Application ClassLoader加载;
  6. 如果Application ClassLoader也加载失败,就会使用自定义加载器去尝试加载;
  7. 如果均加载失败,就会抛出ClassNotFoundException异常。
  • 优点:Java类伴随其类加载器具备了带有优先级的层次关系,确保了在各种环境下的加载顺序。 保证了运行的安全性,防止不可信类扮演可信任的角色。

如何自定义类加载器?

  • 正常方式:继承ClassLoader类并实现findClass方法;
  • 破坏双亲委派:继承ClassLoader类重写loadClass方法。

自定义类加载器有哪些使用场景?

  • 隔离加载类。例如在某些框架内进行中间件与应用的模块隔离,把类加载到不同环境。
  • 修改类加载方式。类的加载模型并非强制,除了Bootstrap ClassLoader外,其他的加载并非一定要引入。可以按需动态加载。
  • 扩展加载源。例如从数据库、网络,甚至电视机机顶盒进行加载。
  • 防止源码泄漏。Java代码容易被编译和篡改,可以通过自定义类加载器进行编译加密。

有哪些开源实现破坏了双亲委派?

  • tomcat
    • tomcat是可以部署多个项目的,那么每个项目的公共的基础类只需要加载一次,而自定义类则需要隔离加载;
    • 对于一些需要加载的非基础类,会由一个叫作 WebAppClassLoader 的类加载器优先加载。等它加载不到的时候,再交给上层的 ClassLoader 进行加载。这个加载器用来隔绝不同应用的 .class 文件,比如你的两个应用,可能会依赖同一个第三方的不同版本,它们是相互没有影响的。

img

  • SPI
    • 典型的例子就是JDBC加载数据库驱动;
    • JDK提供了统一的JDBC驱动接口Driver,各种数据库厂商(MySQL、Oracle等)会根据SPI规范,以jar包形式提供自己的实现。对于实现类的查找与加载本就属于JDK的职责范畴,但是这些实现类都存在于classpath路径下,顶层的双亲类加载器是无法找到的,需要借助子加载器AppClassLoader才能加载,但这又违背双亲委派原则。
    • 为了解决这个问题,Java设计师引入了一种线程上下文类加载器(Thread Context ClassLoader),可以通过Thread类的setContextClassLoader()方法进行设置,如果没有设置,默认就是AppClassLoader。这样便可以可以利用线程上下文加载器去加载SPI的实现类,实现一种父类加载器请求子类加载器完成类加载的行为。虽然这样违背了双亲委派原则,但也解决了一些特殊需求。

能否自定义一个java.lang.Object类?

  • 不能:

    https://hujinyang.blog.csdn.net/article/details/104113847

    • 正常情况下类加载过程会遵循双亲委派机制,依次向上级类加载器委托加载,上级都加载不了,才会自行加载。
    • 如果想绕过双亲委派机制,需要覆写ClassLoader类的loadClass方法,一般不推荐这么做。
    • 由于final方法defineClass的限制,正常情况下我们无法加载以“java.”开头的系统类。
    • 一般自定义类加载器只需实现ClassLoader的findClass方法来加载自定义路径下的类,而不是覆写loadClass破坏双亲委派,避免带来系统安全隐患。

编译原理

什么是解释执行?什么是编译执行?

  • 解释执行:解释器对程序逐条翻译成机器语言,然后再由计算机执行,优点就是可以立刻执行,无需预热,不会产生新代码;
  • 编译执行:编译器将程序一次性翻译成机器语言,后续可以直接执行,集成更多优化,有效提升执行效率,缺点是需要预热等待生成机器码。

JIT即时编译器的作用是什么?

  • 虚拟机将热点代码编译成与本地平台相关的机器码,从而提高热点代码的执行效率;
  • 同时JIT还能做一些代码级的优化,如方法内联、栈上分配、锁消除、锁粗化等。

什么是方法内联?

  • 方法内联指的是,把一些短小的方法体,直接纳入目标方法的作用范围之内,就像是直接在代码块中追加代码。这样,就少了一次方法调用,执行速度就能够得到提升。

除了基本数据类型,一定是在堆上分配的吗?

  • 不一定,通过逃逸分析,JVM 能够分析出一个新的对象的使用范围,从而决定是否要将这个对象分配到堆上。

什么是逃逸分析?

  • 对象被赋值给成员变量或者静态变量,或者作为返回结果返回,可能被外部使用,变量就发生了逃逸。

什么是栈上分配?

  • 如果一个对象在子程序中被分配,指向该对象的指针永远不会逃逸,对象有可能会被优化为栈分配。栈分配可以快速地在栈帧上创建和销毁对象,不用再分配到堆空间,可以有效地减少 GC 的压力;
  • JIT可以将某些没有逃逸出方法的对象优化成栈上分配。

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

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

相关文章

md0和md1linux软raid,软RAID管理命令mdadm详解

mdadm是linux下用于创建和管理软件RAID的命令&#xff0c;是一个模式化命令。但由于现在服务器一般都带有RAID阵列卡&#xff0c;并且RAID阵列卡也很廉价&#xff0c;且由于软件RAID的自身缺陷(不能用作启动分区、使用CPU实现&#xff0c;降低CPU利用率)&#xff0c;因此在生产…

Spring、SpringBoot常见面试题与答案

Spring Spring Bean 的作用域有哪些&#xff1f;它的注册方式有几种&#xff1f; Spring 容器中管理一个或多个 Bean&#xff0c;这些 Bean 的定义表示为 BeanDefinition 对象&#xff0c;具体包含以下重要信息&#xff1a; Bean 的实际实现类&#xff1b;Bean 的引用或者依赖…

c语言本身有输入输出语句正确错误,C语言模拟选择题

导出试题1. 以下叙述正确的是。A) 在C程序中&#xff0c;main函数必须位于程序的最前面B) C程序的每行中只能写一条语句C) C语言本身没有输入输出语句D) 在对一个C程序进行编译的过程中&#xff0c;可发现注释中的拼写错误2. 以下叙述不正确的是。A) 一个C源程序可由一个或多个…

Dubbo常见面试题与答案

Dubbo的基础知识 Dubbo的核心架构是怎样的&#xff1f; Registry&#xff1a;注册中心。 负责服务地址的注册与查找&#xff0c;服务的 Provider 和 Consumer 只在启动时与注册中心交互。注册中心通过长连接感知 Provider 的存在&#xff0c;在 Provider 出现宕机的时候&#…

99行不用指针 c语言贪食蛇,关于C语言指针的问题

#include"iostream.h"structstudent{longnum;intscore;student*next;};student*creat();voidprint(student*head);student*insert(student*head,student*stud);student*del(student*head,longnum);voidmain(){student*headNULL,*stud;longnum;intscore;cout<建立学…

Redis常见面试题与答案

Redis的基本数据类型 Redis有哪些常用的数据类型&#xff1f; String&#xff1a;字符串&#xff08;最常用的缓存&#xff09;Hash&#xff1a;哈希&#xff08;保存对象&#xff09;List&#xff1a;有序列表&#xff08;消息队列&#xff09;Set&#xff1a;无序集合&…

c语言利用文件体写在桌面上,在C语言中怎样新建一个文件夹?

满意答案JacinthLancet推荐于 2017.10.12采纳率&#xff1a;56% 等级&#xff1a;12已帮助&#xff1a;35899人函数名: mkdir功 能: 建立一个目录(文件夹)用 法: int mkdir(char *pathname);程序例: (在win-tc和Dev-c下运行通过)#include #include #include int main(void){…

MySQL常见面试题与答案

存储引擎 InnoDB的主要特点是什么&#xff1f; MySQL5.5版本之后的默认存储引擎&#xff1b;支持事务&#xff1b;支持行级锁&#xff1b;支持MVCC&#xff1b;支持聚集索引方式存储数据。 InnoDB与MyISAM的区别&#xff1f; 存储引擎MyISAMInnoDB存储结构MyISAM在磁盘上存…

C语言6F多少,求助!!请人帮忙画C语言程序流程图.紧急!!!

#include <stdio.h>#define N 10struct student //第一步, 根据具体情况定义结构体类型。{ double num; /*学号*/float score[5]; //数组依次存放英语,数学,计算机基础及平均分};void input( struct student arr[ ], int ) ; /*函数原型*/void aver ( struct student arr…

java如何将String转换为enum

问题 假设定义了如下的enum&#xff08;枚举&#xff09;&#xff1a; public enum Blah {A, B, C, D }已知枚举对应的String值&#xff0c;希望得到对应的枚举值。例如&#xff0c;已知"A"&#xff0c;希望得到对应的枚举——Blah.A&#xff0c;应该怎么做&#x…

java解析c语言的结构体,JAVA中如何实现C中的结构体数组的功能?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼比如我想实现在C中的结构体数组&#xff1a;struct student{string Sno;string Sname;string Sgen;string Sdept;int Sage;student(){Sno "";Sname "";Sgen "男";Sdept "";Sage 0;}}…

Java 解决跨域问题

JAVA | Java 解决跨域问题 文章目录JAVA | Java 解决跨域问题引言什么是跨域&#xff08;CORS&#xff09;什么情况会跨域解决方案前端解决方案后端解决方案具体方式一、使用Filter方式进行设置二、继承 HandlerInterceptorAdapter三、实现 WebMvcConfigurer四、使用Nginx配置五…

c语言写天气预报程序,微信小程序实现天气预报功能

获取应用实例var app getApp()Page({data: {//加载状态loadingHidden: false,//当前温度currentTemperature: ,//夜间温度nightAirTemperature: ,//白天温度dayAirTemperature: ,//当前天气weather: ,//污染指数aqi: ,//污染程度quality: ,//风力windPower: ,//风向windDirect…

Spring 异常处理三种方式

Spring 异常处理三种方式 异常处理方式一. ExceptionHandler异常处理方式二. 实现HandlerExceptionResolver接口异常处理方式三. ControllerAdviceExceptionHandler三种方式比较说明(强烈推荐各位看一下&#xff0c;我觉得自己总结的比较多&#xff0c;嘿嘿&#xff0c;不对之…

Netty常见面试题 与 答案

Netty基础知识 什么是Netty&#xff1f; Netty 是一款用于高效开发网络应用的 NIO 网络框架&#xff0c;它大大简化了网络应用的开发过程&#xff1b; 封装了JDK底层的NIO模型&#xff0c;提供高度可用的API&#xff0c;用于快速开发高性能服务端和客户端&#xff1b;精心设计…

c语言’内存清除函数,c语言常用内存处理函数

memset()#includevoid*memset(void*s,int c,size_t n);功能&#xff1a;将s的内存区域的前n个字节以参数c填入(用来初始化)参数&#xff1a;s:需要操作内存s的首地址c:填充的字符&#xff0c;c虽然参数为int,但必须是unsigned char,范围为0-255n:指定需要设置的大小返回值&…

c语言编俄罗斯方块有注释,C语言学习1年-俄罗斯方块(无注释)

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include #include #include #include int randtmp3,i,j,p,q,fx,fy,s,t,c,r,dltm,begin0,fq,k,a,sj,score0;int dla32000;int nx[5],ny[5],h[5],m[25];int x[8][4]{0,0,0,0,0,-2,-1,0,0,0,1,2,0,0,0,0,0,-1,0,1,0,0,1,1,0…

使用 @ControllerAdvice 和 实现ResponseBodyAdvice接口, 拦截Controller方法默认返回参数,统一处理返回值/响应体

使用 ControllerAdvice 和 实现ResponseBodyAdvice接口&#xff0c; 拦截Controller方法默认返回参数&#xff0c;统一处理返回值/响应体 1、Controller代码 以下是Controller方法源码&#xff1a; RestController RequestMapping("/manage/user") public class Te…

c语言中字符占用的存储单元,C语言知识点第1章.doc

C语言知识点第1章C语言知识点总结(二) 第八节 字符字符常量定义&#xff1a;一对单引号括起来的一个字符。如‘A’、‘a’、‘9’相应字符对应的ASCII编码值(见附录四)字符常量占用一个字节的存储单元(一个字节占8位)重点&#xff1a;表 C语言中常见的转义字符字符形式意义字符…

Spring的@ExceptionHandler注解使用方法

文章目录1&#xff0c;基本使用方法2&#xff0c;注解的参数3&#xff0c;就近原则4&#xff0c;注解方法的返回值5&#xff0c;错误的操作1&#xff0c;基本使用方法 Spring的ExceptionHandler可以用来统一处理方法抛出的异常&#xff0c;比如这样&#xff1a; ExceptionHan…