【2021最新版】JVM面试题总结(87道题含答案解析)

文章目录

最近面试的小伙伴不少,对此我整理了一份Java面试题手册:基础知识、JavaOOP、Java集合/泛型面试题、Java异常面试题、Java中的IO与NIO面试题、Java反射、Java序列化、Java注解、多线程&并发、JVM、Mysql、Redis、Memcached、MongoDB、Spring、SpringBoot、SpringCloud、RabbitMQ、Dubbo、MyBatis、ZooKeeper、数据结构、算法、Elasticsearch、Kafka、微服务、Linux等等。能够分享给你们学习。【持续更新中】java

完整版Java面试题地址:【2021最新版】Java面试真题汇总程序员

序号 内容 地址连接
1 【2021最新版】JavaOOP面试题总结 http://www.noobyard.com/article/p-rncfmibs-oe.html
2 【2021最新版】Java基础面试题总结 http://www.noobyard.com/article/p-ykqnztan-oe.html
3 【2021最新版】多线程&并发面试题总结 http://www.noobyard.com/article/p-nhidektg-oe.html
4 【2021最新版】Mysql面试题总结 未更新
5 【2021最新版】Redis面试题总结 未更新
6 【2021最新版】Memcached面试题总结 未更新
7 【2021最新版】MongoDB面试题总结 未更新
8 【2021最新版】Spring面试题总结 未更新
9 【2021最新版】Spring Boot面试题总结 未更新
10 【2021最新版】Spring Cloud面试题总结 未更新
11 【2021最新版】RabbitMQ面试题总结 未更新
12 【2021最新版】Dubbo面试题总结 未更新
13 【2021最新版】MyBatis面试题总结 未更新
14 【2021最新版】ZooKeeper面试题总结 未更新
15 【2021最新版】数据结构面试题总结 未更新
16 【2021最新版】算法面试题总结 未更新
17 【2021最新版】Elasticsearch面试题总结 未更新
18 【2021最新版】Kafka面试题总结 未更新
19 【2021最新版】微服务面试题总结 未更新
20 【2021最新版】Linux面试题总结 未更新

一、Java中会存在内存泄漏吗,请简单描述。

答:web

会,本身实现堆载的数据结构时有可能会出现内存泄露,可参看effective java。面试

二、64位JVM中,int的长度是多数?

三、Serial与Parallel GC之间的不一样之处?

四、32位和64位的JVM,int类型变量的长度是多数?

答:算法

32位和64位的JVM中,int类型变量的长度是相同的,都是32位或者4个字节。sql

五、Java中WeakReference与SoftReference的区别?

六、JVM选项-XX:+UseCompressedOops有什么做用?为何要使用?

七、怎样经过Java程序来判断JVM是32位仍是64位?

八、32位JVM和64位JVM的最大堆内存分别是多数?

九、JRE、JDK、JVM及JIT之间有什么不一样?

十、解释Java堆空间及GC?

十一、JVM内存区域

答:

JVM内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA堆、方法区】、直接内存。编程

线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 建立/销毁(在Hotspot VM内, 每一个线程都与操做系统的本地线程直接映射, 所以这部份内存区域的存/否跟随本地线程的生/死对应)。服务器

线程共享区域随虚拟机的启动/关闭而建立/销毁。数据结构

直接内存并非JVM运行时数据区的一部分, 但也会被频繁的使用:在JDK1.4引入的NIO提供了基于Channel与Buffer的IO方式, 它可使用Native函数库直接分配堆外内存, 而后使用DirectByteBuffer对象做为这块内存的引用进行操做(详见:Java I/O扩展), 这样就避免了在Java堆和Native堆中来回复制数据, 所以在一些场景中能够显著提升性能。多线程

十二、程序计数器(线程私有)

答:

一块较小的内存空间, 是当前线程所执行的字节码的行号指示器,每条线程都要有一个独立的程序计数器,这类内存也称为“线程私有” 的内存。

正在执行java方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址) 。若是仍是Native方法,则为空。
这个内存区域是惟一一个在虚拟机中没有规定任何OutOfMemoryError状况的区域。

1三、虚拟机栈(线程私有)

答:

是描述java方法执行的内存模型,每一个方法在执行的同时都会建立一个栈帧(Stack Frame)用于存储局部变量表、操做数栈、动态连接、方法出口等信息。 每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
栈帧( Frame)是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态连接(Dynamic Linking)、 方法返回值和异常分派(Dispatch Exception)。 栈帧随着方法调用而建立,随着方法结束而销毁——不管方法是正常完成仍是异常完成(抛出了在方法内未被捕获的异常)都算做方法结束。

1四、本地方法区(线程私有)

答:

不能,虽然你能够调用System.gc() 或者Runtime.gc(),可是没有办法保证GC的执行。

1五、你能保证GC执行吗?

1六、怎么获取Java程序使用的内存?堆使用的百分比?

答:

能够经过java.lang.Runtime类中与内存相关方法来获取剩余的内存,总内存及最大堆内存。经过这些方法你也能够获取到堆使用的百分比及堆内存的剩余空间。Runtime.freeMemory() 方法返回剩余空间的字节数,Runtime.totalMemory()方法总内存的字节数,Runtime.maxMemory() 返回最大内存的字节数。

1七、Java中堆和栈有什么区别?

1八、描述一下JVM加载class文件的原理机制

1九、GC是什么?为何要有GC?

答:

GC是垃圾收集的意思 ,内存处理是编程人员容易出现问题的地方 ,忘记或者错误的内存回收会致使程序 或系统的不稳定甚至崩溃,Java提供的GC功能能够自动监测对象是否 超过做用域从而达到自动回收内存的目的 ,Java语言没有提供释放已分配内存的显示操做方法 。Java程序员不用担忧内存管理, 由于垃圾收集器会自动进行管理 。要请求垃圾收集 ,能够调用下面的方法之一 :System.gc() 或Runtime.getRuntime().gc() ,但JVM能够屏蔽掉显示的垃圾回收调用 。

垃圾回收能够有效的防止内存泄露,有效的使用可使用的内存。垃圾回收器一般是做为一个单独的低优先级的线程运行,不可预知的状况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或全部对象进行垃圾回收。在Java诞生初期,垃圾回收是Java最大的亮点之一,由于服务器端的编程须要有效的防止存泄露问题,然而时过境迁,现在Java的垃圾回收机制已经成为被诟病的东。移动智能终端用户一般以为iOS的系统比Android系统有更好的用户体验,其中一个深层次的缘由就在于Android系统中垃圾回收的不可预知性。

20、堆(Heap-线程共享)-运行时数据区

2一、方法区/永久代(线程共享)

2二、JVM运行时内存

答:

Java堆从GC的角度还能够细分为:新生代(Eden 区、From Survivor区和To Survivor区)和老年代

2三、新生代

2四、老年代

2五、永久代

2六、JAVA8与元数据

2七、引用计数法

2八、可达性分析

2九、标记清除算法(Mark-Sweep)

答:
最基础的垃圾回收算法,分为两个阶段,标注和清除。标记阶段标记出全部须要回收的对象,清除阶段回收被标记的对象所占用的空间。

如图

从图中咱们就能够发现,该算法最大的问题是内存碎片化严重,后续可能发生大对象不能找到可利用空间的问题。

30、复制算法(copying)

答:

为了解决 Mark-Sweep 算法内存碎片化的缺陷而被提出的算法。按内存容量将内存划分为等大小的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另外一块上去,把已使用的内存清掉。

如图:

这种算法虽然实现简单,内存效率高,不易产生碎片,可是最大的问题是可用内存被压缩到了本来的一半。且存活对象增多的话, Copying算法的效率会大大下降。

3一、标记整理算法(Mark-Compact)

答:
结合了以上两个算法,为了不缺陷而提出。标记阶段和 Mark-Sweep 算法相同, 标记后不是清理对象,而是将存活对象移向内存的一端。而后清除端边界外的对象。

如图

3二、分代收集算法

3三、新生代与复制算法

答:

目前大部分JVM 的 GC对于新生代都采起Copying算法,由于新生代中每次垃圾回收都要回收大部分对象,即要复制的操做比较少,但一般并非按照1: 1来划分新生代。通常将新生代划分为一块较大的Eden空间和两个较小的Survivor空间(From Space, To Space),每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将该两块空间中还存活的对象复制到另外一块Survivor空间中。

3四、老年代与标记复制算法

3五、JAVA强引用

3六、JAVA软引用

3七、JAVA弱引用

3八、JAVA虚引用

3九、分代收集算法

40、在新生代-复制算法

4一、在老年代-标记整理算法

4二、分区收集算法

4三、GC垃圾收集器

答:

Java堆内存被划分为新生代和年老代两部分,新生代主要使用复制和标记-清除垃圾回收算法;年老代主要使用标记-整理垃圾回收算法,所以java虚拟中针对新生代和年老代分别提供了多种不一样的垃圾收集器, JDK1.6中Sun HotSpot虚拟机的垃圾收集器以下:

4四、Serial垃圾收集器(单线程、 复制算法)

4五、ParNew垃圾收集器(Serial+多线程)

4六、Parallel Scavenge收集器(多线程复制算法、高效)

5七、Serial Old收集器(单线程标记整理算法 )

答:

Serial Old是Serial垃圾收集器年老代版本,它一样是个单线程的收集器,使用标记-整理算法,这个收集器也主要是运行在 Client默认的java虚拟机默认的年老代垃圾收集器。在Server模式下,主要有两个用途:

  1. 在 JDK1.5 以前版本中与新生代的Parallel Scavenge收集器搭配使用。

  2. 做为年老代中使用CMS收集器的后备垃圾收集方案。新生代 Serial 与年老代 Serial Old 搭配垃圾收集过程图:
    在这里插入图片描述
    新生代Parallel Scavenge收集器与ParNew收集器工做原理相似,都是多线程的收集器,都使用的是复制算法,在垃圾收集过程当中都须要暂停全部的工做线程。新生代ParallelScavenge/ParNew与年老代Serial Old搭配垃圾收集过程图:

5八、Parallel Old收集器(多线程标记整理算法)

5九、CMS收集器(多线程标记清除算法)

60、G1收集器

6一、JVM类加载机制

6二、类加载器

答:

虚拟机设计团队把加载动做放到JVM外部实现,以便让应用程序决定如何获取所需的类,JVM提供了3 种类加载器:
启动类加载器(Bootstrap ClassLoader) 负责加载JAVA_HOME\lib目录中的,或经过-Xbootclasspath参数指定路径中的,且被虚拟机承认(按文件名识别, 如 rt.jar)的类。

扩展类加载器(Extension ClassLoader)负责加载 JAVA_HOME\lib\ext 目录中的,或经过java.ext.dirs系统变量指定路径中的类库。应用程序类加载器(Application ClassLoader):

负责加载用户路径(classpath)上的类库。JVM 经过双亲委派模型进行类的加载, 固然咱们也能够经过继承java.lang.ClassLoader实现自定义的类加载器。

6三、双亲委派

6四、OSGI(动态模型系统)

6五、动态改变构造

6六、模块化编程与热插拔

6七、JVM内存模型

6八、栈

6九、本地方法栈

70、程序计数器

7一、堆

7二、方法区

7三、分代回收

答:

分代回收基于两个事实:大部分对象很快就不使用了,还有一部分不会当即无用,但也不会持续很长时间

年轻代->标记-复制

老年代->标记-清除

7四、堆和栈的区别

7五、何时会触发FullGC

7六、什么是Java虚拟机?为何Java被称做是“平台无关的编程语言”?

7七、对象分配规则

7八、描述一下JVM加载class文件的原理机制?

7九、Java对象建立过程

80、简述Java的对象结构

8一、如何判断对象能够被回收

8二、JVM的永久代中会发生垃圾回收么

8三、垃圾收集算法

8四、调优命令有哪些?

8五、调优工具

8六、Minor GC与Full GC分别在何时发生?

8七、你知道哪些JVM性能调优

答:

设定堆内存大小-Xmx:堆内存最大限制。

设定新生代大小。 新生代不宜过小,不然会有大量对象涌入老年代

-XX:NewSize:新生代大小

-XX:NewRatio 新生代和老生代占比

-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比

设定垃圾回收器 年轻代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC

总结

该面试题答案解析完整文档获取方式:JVM面试题总结

篇幅有限,其余内容就不在这里一 一展现了,整理不易,欢迎你们一块儿交流,喜欢小编分享的文章记得关注我点赞哟,感谢支持!重要的事情说三遍,转发+转发+转发,必定要记得转发哦!!!