JVm面试题精选

本文深入探讨了JVM的类加载机制,包括何时加载类、初始化过程、类加载器类型及其关系、双亲委派模型及其优势与打破方式。此外,还详细阐述了JVM内存结构,包括堆、栈、方法区等区域的特性和应用,以及对象分配、内存管理和垃圾回收的原则。最后,介绍了不同引用类型、内存泄漏与溢出的概念,并分享了线上环境JVM的配置实践和CPU异常排查方法。
摘要由CSDN通过智能技术生成

类加载机制

面试题1:java运行时一个类什么时候被加载?

虚拟机,应用最广的就是sun/oracle公司的hotspot虚拟机,是按需加载的,最开始会先加载核心类库rt.jar中的lang包下的Object、Serializable等类,后面就是用到什么类加载什么类

面试题2:一个类被初始化的过程?

初始化顺序:
静态常量在准备阶段已经被赋值,静态变量被赋值,静态代码块被执行。变量、初始化块在构造器之前执行,这三个都是在创建对象时执行。

面试题3:什么是类加载器?

在类加载过程中,通过一个类的全限定名称获取描述该类的二进制流文件的这个动作的”代码“ 被称为 ”类加载器“(Class Loader),这个动作是可以自定义实现的。(可能是java、c++)

简单来讲,类加载器就是一段程序、一段代码,用以通过全限定名称读取.class文件。

面试题4:JVm有哪些类加载器?

1.启动类加载器BootStrap Class Loader。 c++编写的,是虚拟机身的一部分。除这之外其他加载器都是java编写的。
2.扩展类加载器(Extension Class Loader)。负责加载/lib/ext目录中,或者被Java.ext.dirs系统变量所指定的路径中所有的类库。由java实现的代码,就是Java系统类库的一种扩展机制。
3.应用程序类加载器 (Application Class Loader)。负责加载用户类路径(ClassPath)上所有的类库,开发者可以在代码中使用这个类加载器。

面试题5:Jvm三层类加载器之间的关系是继承吗?

不是。BootStrap Class Loader. 是c++编写的,并不能由扩展类加载器和应用程序类加载器继承,它们两个都是由java编写的,继承于UrlClassLoader类,然后最上面继承的是ClassLoader类。我们自定义的加载器也是继承于ClassLoader类。

面试题6: 你了解JVm类加载的双亲委派模型吗?

如果一个类加载器收到了类加载的请求,他首先不会自己去加载这个类,而是把这个类委派给父类去加载,每一层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器无法完成这个加载请求(它的搜索范围中欸有找到所需要的类)时,子加载器才会尝试自己去完成加载。

面试题7: JDK为什么要设计双亲委派模型,这样有什么好处?

1.确保安全,避免核心类库被修改
2.避免重复加载,保证类的唯一性

面试题8:可以打破JVM双亲委派模型吗?如何打破

可以。通过自定义类加载器,重写其中的loadClas方法,因为底层应用程序类加载器调用的就是loadClass()方法,而在这个方法内部具体实现双亲委派模型的代码,其实是调用的父类的loadClass()方法来实现。所以我们只需要在我们自己重写的loadClass()方法中不实现双亲委派即可。

面试题9:如何自定义类加载器?

1.继承ClassLoader,重写find Class()方法或loadClass()方法
2.重写findClass() ,不会打破双亲委派;重写loadClass会打破双亲委派。

面试题10:ClassLoader中loadClass()、findClass()、defineClass()的区别?

loadClass() 就是主要进行类加载的方法,默认的双亲委派机制就实现在loadClass()方法中;
findClass()根据名称加载.class字节码;
defineClass()把字节码转化为java.lang.Class;

面试题11: 如何实现热加载?

1.实现自己的类加载器
2.从自己的类加载器中加载要热加载的类
3.不断轮询要热加载的类class文件是否有更新,如果有更新,重新加载

JVm内存管理

面试题12: 请介绍一个JVM内存结构划分?

在这里插入图片描述

面试题13: 请说明一下JVM的整个运行原理

在这里插入图片描述
1.通过javac源文件(java文件)编译成字节码文件(.class文件
2.通过类加载子系统把字节码文件加载到 jvm 内存的元空间(方法区,jdk1.8后变为元空间)中
3.然后main方法开始执行,此时会创建一个虚拟机栈(也可以叫方法栈或线程栈),main方法里的代码就在虚拟机栈中执行
4.在代码执行过程中局部变量会存储在虚拟机栈中,引用的对象放在中,程序计数器用于记录代码执行到第几行
5.如果在执行过程中调用了本地方法(由C++编写的native方法),则会创建一个本地方法栈用于执行native方法。

面试题14:JVM 哪些区域是私有的?哪些是共享的?

还是这张图,可以看到,元空间共享的虚拟机栈本地方法栈程序计数器私有的。
所以这就导致
1.堆和元空间会存在安全性问题;
2.多个线程会生成多个虚拟机栈、程序计数器和本地方法栈,因为是私有的,一个虚拟机栈、程序计数器或本地方法栈只会对应一个线程;
在这里插入图片描述

面试题15:JVM运行时数据区 虚拟机栈的特点及应用?

1.线程私有
2.方法执行会创建栈帧,存储局部变量表、操作数栈、动态连接、方法出口等信息。
3.方法执行入虚拟机栈,方法执行完出虚拟机栈
4.线程请求的栈深度大于虚拟机所允许的深度,抛出StackOVerflowError异常(递归时比较常见)
5.栈扩展时无法申请到足够的内存,抛出OutOfMemoryError异常(少见);hotSpot虚拟机没有
6.栈里面运行的方法,存放方法的局部变量名,变量名所指向的变量值(常量值、对象值等)都是存储在堆中的。
7.栈一般不设置大小,占用空间很小,可以通过“-Xss”加上需要设置的大小进行设置(-Xss1k就是栈只有1k的大小),如果不设置默认为1M
8.随线程而生,随线程灭
9.不会被GC回收

面试题15:JVM本地方法栈的特点及应用?

与虚拟机栈基本相同,区别在于虚拟机栈为虚拟机执行java方法服务,本地方法栈为虚拟机执行本地方法服务。

面试题16:JVM运行时数据区 java堆的特点及应用?

1.线程共享
2.在虚拟机启动时创建
3.是虚拟机管理的内存中最大 的一*个区域
4.存放几乎所有的实例或对象
5.GC垃圾收集器的主要管理区域
6.可分为新生代,老年带
7.新生代可分为Eden、From Survivor 和 To Survivor,空间占比为8:1:1
8.可通过 -Xms 和 -Xmx调节堆大小
9.如果堆无法扩展,抛出OutOfMemoryError异常
10.如果从分配内存角度看,所有线程共享的java堆中可以划分出多分线程私有的分配缓冲区(THread Local Allocation Buffer ,TLAB),以提升对象分配时的效率.
在这里插入图片描述

面试题17:JVM对象如何在堆内存中分配?

1.指针碰撞 把使用的内存和空闲的内存用一个指针分隔开,分配对象时,只需要把指针挪动一段距离即可;
2.空闲列表 因为有些java堆中的内存不一定是规整的,已使用的和空闲的交错在一起,这时候就需要一个列表用于纪律内存块的状态,在分配的时候从列表中找出一块足够大的空间分配给对象实例,并更新列表上的记录.
3.选择哪种方式由java堆是否规整决定,而java堆是否规整,又由所采用的垃圾收集器是否带有空间压缩整理(Compact)的能力决定.
所以当使用Serial\ParNew等带压缩整理过程的垃圾收集器是,系统采用指针碰撞, 既简单又高效;而当使用CMS这种基于清除(Sweep)算法的收集器时,理论上只能使用空闲列表
4.在并发情况下线程并不是安全的,可能出现正在给A分配内存,指针还没来得及修改, 对象B又同时使用了原来的指针来分配内存的情况.
解决方案:
(1) 同步锁定,使用CAS配上失败重试的方式保证更新操作的原子性
(2)线程隔离,把内存分配动作按照 线程划分在不同的空间之中进行,即每个线程先预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB), 哪个线程要分配内存,就在哪个线程的本地缓冲区中分配.

面试18:JVm如何判断对象可以被回收?

通过可达性分析 判断对象是否与“GcRoot节点有链接,有连接则称为可达的,不回收;没有链接,则称为不可达达的,将会被GC回收。

面试题19:谈谈 java中不同引用类型

强引用:Object obj = new Object();
软引用:SoftReference。内存不够才会回收。
弱引用: WeakReference。垃圾收集器一运行,就会被回收。
虚引用:最弱的一种引用,对 对象的生存时间不会构成影响,我们无法通过虚引用来获取一个实例

面试题20:什么是内存泄漏和内存溢出?

内存泄漏:程序运行之后,没有释放所占用的空间,一次内存泄漏可能不会有什么影响,但长时间内存泄漏,堆积到一定程度就会产生内存溢出。
一些连接没有关闭可能会导致内存泄漏,如数据库连接、socket、io都必须close,否则不能被回收。

面试题21:你们线上环境的JVM都设置多大?

线上:4核8G
jvm::栈、堆、元空间
栈:一个线程1M ,一个线上项目tomcat可能有300个线程,300M;
堆:大概机器的一半,4G(新生代,老年代)
CMS 新 :老=1:2 G1 6:4
元空间:一般512M就够了

面试题22:java项目cpu飙升到100%怎么排查?

top
top -H -p pid
printf ‘%x’tid 8ef
jstack pid

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值