JVM常见面试题

JVM常见面试题

\1. 说一下 jvm 的主要组成部分?及其作用?

类加载器子系统:加载类文件到内存

执行引擎:也叫解释器,负责解释命令,交由操作系统执行。

本地方法接口:本地接口的作用是融合不同的语言为java所用

运行时数据区:

\2. 说一下 jvm 运行时数据区?

程序计数器:指示Java虚拟机下一条需要执行的字节码指令。

Java 虚拟机栈:存储当前线程的运行方法时所需的数据

虚拟机栈中执行每个方法的时候,都会创建一个栈桢用于存储局部变量表,操作数栈,动态链接,方法出口等信息

本地方法栈:为虚拟机运行native方法服务

堆:存放的是存放对象实例和数组,是所有线程共享的内存区域

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HK9vsL5U-1593930449981)(file:///C:/Users/10145/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)]Eden:s1:s2 = 8:1:1

方法区:用于存储已被虚拟机加载的类信息(class文件)、常量(1.7有变化存储在堆里面)、静态变量

\3. 说一下堆栈的区别?

l 栈内存存储的是局部变量而堆内存存储的是实体;

l 栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

l 栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

\4. 队列和栈是什么?有什么区别?

都是运算受限制的线性表

队列:只允许在前端进行删除,后端进行插入

栈:仅允许在表的一端进行插入和删除运算。

5.什么是双亲委派模型?

双亲委派模型是描述类加载器之间的层次关系。它要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。(父子关系一般不会以继承的关系实现,而是以组合关系来复用父加载器的代码)

收到类加载请求时,会先将请求委派给父类加载器,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(找不到所需的类)时,子加载器才会尝试自己去加载。

作用:

1、防止重复加载同一个**.class**。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
2、保证核心.class不能被篡改。通过委托方式,不会去篡改核心.clas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

6.说一下类加载的执行过程?

加载 连接(验证 准备 解析)初始化

加载:将类的class文件读入到内存,并为之创建一个java.lang.Class对象

验证:检验被加载的类是否有正确的内部结构

准备:为类的静态变量分配内存,并设置默认初始值

解析:将类的二进制数据中的符号引用替换成直接引用

初始化:为类的静态变量赋予正确的初始值

准备是分配内存,赋默认值(如0),到初始化再赋正确值

7.怎么判断对象是否可以被回收?

若一个对象不被任何对象或变量引用,那么它就是无效对象,需要被回收。

方法一是引用计数器,有对象引用时计数器+1

方法二是可达性分析,从GC Roots向下搜索,当一个对象到GC Roots无引用链则回收

8.java 中都有哪些引用类型?

强引用:最常见的引用类型,不可随意回收,内存不足则抛出OutOfMemoryError错误。

软引用:类似**缓存,**内存够时GC不回收,内存不够时回收

弱引用:当JVM进行垃圾回收时,无论内存是否充足,都会回收只被弱引用关联的对象。

虚引用:约等于没有引用,随时被回收,做为对象是否存活的监控

9.说一下 jvm 有哪些垃圾回收算法?

标记-清除算法:遍历GC Roots,将GC Roots可达的对象进行标记,清除所有未标记对象。

缺点:1.效率不高 2.产生大量内存碎片,会因为没有连续地址无法分配较大对象再进行GC

复制算法:

以往是将内存各分为一半,当GC时,将存活对象复制到另一部分内存中,另一部分全部清除

优点是不会有内存碎片问题,缺点是内存大小缩为原来一半浪费空间

所以为解决空间利用问题将内存分为Eden、From survivor、To survivor,8:1:1

回收时,将 Eden 和 Survivor 中还存活的对象一次性复制到另外一块 Survivor 空间上,最后清理掉 Eden 和刚才使用的 Survivor 空间。这样只有 10% 的内存被浪费。但是无法保证每次只有10%的内存被回收,所以由老年代担保,当超过10%,放入老年代。

标记-整理算法(老年代GC算法)

和标记清楚一样,将标记过的对象整理到连续内存地址上,将之后地址的内容清空

分代收集算法:针对各个年代特点采用适合的算法

新生代:复制算法

老年代:标记-清除 or 标记-整理算法

10.说一下 jvm 有哪些垃圾回收器?

新生代垃圾收集器

Serial垃圾收集器(单线程):只开启条 GC 线程进行垃圾回收,并且在垃圾收集过程中停止一切用户线程,适合客户端(所需内存小,堆内存不大,GC时间短)

ParNew垃圾收集器(多线程):Serial的多线程版本。追求**低停顿时间。**多CPU下比Serial有性能提升,但是线程切换需要额外开销,所以单CPU不如Serial。

Parallel Scavenge 垃圾收集器(多线程):和 ParNew 一样都是多线程、新生代垃圾收集器

但是Parallel Scavenge追求高吞吐量(吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)),适合服务器这种不需要交互的后台计算,而ParNew适合交互式应用。

老年代垃圾收集器

Serial Old 垃圾收集器(单线程):Serial Old工作在老年代,使用标记-整理,Serial工作在新生代,使用复制算法

Parallel Old 垃圾收集器(多线程)

是 Parallel Scavenge 的老年代版本,追求 CPU 吞吐量。

CMS 垃圾收集器

CMS(Concurrent Mark Sweep,并发标记清除)收集器是以获取最短回收停顿时间为目标的收集器(追求低停顿),它在垃圾收集时使得用户线程和 GC 线程并发执行,因此在垃圾收集过程中用户也不会感到明显的卡顿。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WVpFN7cC-1593930449983)(file:///C:/Users/10145/AppData/Local/Temp/msohtmlclip1/01/clip_image003.png)]

缺点:吞吐量低,无法处理浮动垃圾导致频繁Full GC,使用标记-清除算法

G1通用垃圾收集器追求可预测的停顿

将堆分为一块块独立region,每次回收先评估再回收回收价值最大的region

整体看,基于标记-整理算法,局部看基于复制算法,以为着不会产生空间碎片,

12.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

新生代3个:serial、parnew、parallel scavenge

老年代3个:serial old、parallel old、CMS

区别:可能工作区域不同吧

13.简述分代垃圾回收器是怎么工作的?

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。 新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,

它的执行流程如下:

把 Eden + From Survivor 存活的对象放入 To Survivor 区;

清空 Eden 和 From Survivor 分区; From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。

每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代。//长期存活对象进入老年代

老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的执行算法。

14.说一下 jvm 调优的工具?

一、jps:虚拟机进程状况工具:显示指定系统内所有的HotSpot虚拟机进程

二、jstat:虚拟机统计信息监视工具:用于监视虚拟机运行时状态信息的命令

三、jmap:Java内存印象工具

四、jhat:虚拟机堆转储快照分析工具

五、jstack:Java堆栈跟踪工具

六、jinfo:Java配置信息工具

15.常用的 jvm 调优的参数都有哪些?

参数名称含义默认值
-Xms初始堆大小物理内存的1/64(<1GB)默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
-Xmx最大堆大小物理内存的1/4(<1GB)默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xmn年轻代大小(1.4or lator)注意:此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
-XX:NewSize设置年轻代大小(for 1.3/1.4)
-XX:MaxNewSize年轻代最大值(for 1.3/1.4)
-XX:PermSize设置持久代(perm gen)初始值物理内存的1/64
-XX:MaxPermSize设置持久代最大值物理内存的1/4
-Xss每个线程的堆栈大小JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右一般小的应用, 如果栈不是很深, 应该是128k够用的 大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。(校长)和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:"”-Xss is translated in a VM flag named ThreadStackSize”一般设置这个值就可以了。
-XX:ThreadStackSizeThread Stack Size(0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.]
-XX:NewRatio年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)-XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。
-XX:SurvivorRatioEden区与Survivor区的大小比值设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
-XX:LargePageSizeInBytes内存页的大小不可设置过大, 会影响Perm的大小=128m
-XX:+UseFastAccessorMethods原始类型的快速优化
-XX:+DisableExplicitGC关闭System.gc()这个参数需要严格的测试
-XX:MaxTenuringThreshold垃圾最大年龄如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活 时间,增加在年轻代即被回收的概率该参数只有在串行GC时才有效.
-XX:+AggressiveOpts加快编译
-XX:+UseBiasedLocking锁机制的性能改善
-Xnoclassgc禁用垃圾回收
-XX:SoftRefLRUPolicyMSPerMB每兆堆空闲空间中SoftReference的存活时间1ssoftly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap
-XX:PretenureSizeThreshold对象超过多大是直接在旧生代分配0单位字节 新生代采用Parallel Scavenge GC时无效另一种直接在旧生代分配的情况是大的数组对象,且数组中无外部引用对象.
-XX:TLABWasteTargetPercentTLAB占eden区的百分比1%
-XX:+CollectGen0FirstFullGC时是否先YGCfalse
                            |

| -XX:+CollectGen0First | FullGC时是否先YGC | false | |

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值