欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JVM面试十问

程序员文章站 2022-05-18 21:13:58
1. JVM运行时划分哪几个区域?哪些区域是线程共享的?哪些区域是线程独占的? JVM运行时一共划分:程序计数器、虚拟机栈、堆、本地方法栈、方法区。 线程共享的数据区域:堆、方法区。 线程独享的数据区域区域:程序计数器、虚拟机栈、本地方法栈。 2. 这几个内存区域分别存放什么数据? 程序计数器记录当 ......

1. jvm运行时划分哪几个区域?哪些区域是线程共享的?哪些区域是线程独占的?

jvm运行时一共划分:程序计数器、虚拟机栈、堆、本地方法栈、方法区。

线程共享的数据区域:堆、方法区。

线程独享的数据区域区域:程序计数器、虚拟机栈、本地方法栈。

2. 这几个内存区域分别存放什么数据?

程序计数器记录当前线程执行的位置;

虚拟机栈存储基本数据类型以及对象的引用等;

堆存储对象实例;

本地方法栈与虚拟机栈类似,它为native方法服务;

方法区存储被jvm加载的类信息、常量、静态变量等。

3. gc回收算法

(1)标记-清除算法:首先标记出需要回收的对象,标记完成后统一清除。此算法缺点是标记-清楚效率不高,且容易出现大量不连续的碎片空间。

(2)复制算法:将内存空间划分成两部分,每次只使用一个内存空间部分,当一个内存空间使用完,将会把存活的对象复制到另一空间,然后一次性清理掉该部分空间。此算法缺点是内存利用率较低,只有一半。

(3)标记-整理算法:和标记-清楚算法相同也是先标记出需要回收的对象,但在标记完成后不是直接清除而是将存活的对象像一侧进行移动,再清除边界之外的内存。

4. 这三种gc回收算法在jvm中是如何应用的?

gc主要发生在jvm的堆内存中,堆内存分为"新生代"和"老年代",新生代的gc称为"minor gc",老年代的gc称为"major gc"。

新生代中的gc算法使用复制算法:新生代中分为了eden区和survivor区(survivor from和survivor to),新产生的对象实例先在eden区,eden区满了过后再在survivor from区,如果survivor from区也满了后,将进行minor gc(复制算法),将存活的对象复制到survivor to区,此时清除eden区和survivor from区,此时survivor from成为新的survivor to。新的对象又将在eden区域进行分配,周而复始。

老年代中的gc算法使用标记-清除算法/标记-整理算法,视具体的gc回收器而定。

5. 频繁的full gc会带来什么问题?

cpu占用率过高,系统出现卡顿。

6. 什么是oom内存溢出,它发生在哪块内存区域

oom通常发生在堆内存上,指的是内存对象没有及时回收,造成没有多余的内存分配给新的对象,此时应该定位程序中是否在频繁创建对象而没有及时回收,或者设置jvm的参数-xms、-xmx。

但oom还有一种情况发生在虚拟机栈,此时虚拟机栈并不是因为递归太深造成*,而是的的确确发生了oom。首先,虚拟机栈作为线程独享的内存区域,总的虚拟机栈内存大小有限,也就是可分配的线程大小有限,当每个虚拟机栈设置的内存大小过大时,此时可分配的线程大小就变少,继续创建过多的线程可能会导致无法再分配内存空间,造成虚拟机栈的oom。此时的解决办法时,适当设置虚拟机栈的内存大小-xss,以便能创建更多的线程。

7.常用的gc回收器有哪些,有什么特点?

cms:通常对老年代的对象进行gc,基于标记-清除算法,是一个低停顿、并发收集的gc回收器。它的gc过程一共分为4个步骤:

①初始标记,标记gc roots能关联的对象(即存活的对象),会停止用户线程。

②并发标记,不会停止用户线程,和用户线程一起工作标记可达对象。

③重新标记,标记因为在“并发标记”阶段新产生的对象。

④并发清除,同用户线程一起工作,清理需要清理的对象。

JVM面试十问

缺点:

①占用cpu资源

②无法处理并发标记期间产生的浮动垃圾

③由于采用标记-清楚算法,会产生大量的内存碎片

g1:应用于整个堆上的内存,物理上不再划分年轻代与老年代,只做逻辑保留,采用标记-整理算法,是一个可对停顿时间预测的低停顿、并发收集的gc回收器。它的gc过程同cms类似,一共分为4个步骤:

①初始标记,同cms回收器一致,标记出存活的对象。

②并发标记,同cms回收器一致,和用户线程并发标记出存活的对象。

③最终标记,同cms回收器一致,修正在并发标记将期间用户线程新产生的对象。

④筛选回收,这个阶段可根据用户期望的gc停顿时间制定回收计划。

JVM面试十问

8. 类在jvm中的加载过程

java文件被编译为class字节码文件后被加载到jvm中,主要分为三步:加载 -> 连接 -> 初始化。连接过程又分为:验证 -> 准备 -> 解析。

JVM面试十问

9. 类是如何被加载到jvm中的

java文件被编译成class字节码文件后,通过类加载器被加载到jvm中。类加载器从上往下一共有:启动类加载器、扩展类加载器、应用程序类加载器、自定义类加载器。类先从自定义类加载器开始,逐层向上传递到启动类加载器,当启动类加载器不能加载时,再向扩展类加载器加载,这称为双亲委派模型。

10. 类加载器的双亲委派模型有什么好处

假设一个类首先被自定义类加载器加载,我们写object类时,系统中就会出现不同的object类。为了保证在系统中始终都只有一个object类,方法就是它们都通过启动类加载器加载。

这是一个能给程序员加buff的公众号 (coderbuff)
JVM面试十问