【Java核心面试宝典】Day12、“Java虚拟机”相关面试题大总结
Hello,你好呀,我是
灰小猿
!一个超会写bug的程序猿!
用坚持缔造技术、用指尖敲动未来!
和很多小伙伴们一样,我也是一名奔波在Java道路上的“创造者
”。也想靠技术来改未来,改变世界!因为我们坚信每一次敲动键盘都能让生活变得更智能、世界变得更有趣
!
在此专栏《Java核心面试宝典》记录我们备战梦想的【day 12】
!
叮叮叮!我又来了。今天给大家带来的是关于Java虚拟机相关的面试题。这部分面试题的理论性有些强,不容易理解,但是偏偏还是很多面试官爱出的内容,没办法,难搞喔~~~
Java虚拟机在执行Java程序的过程中会把他管理的的内存划分成若干个不同的数据区域,这些区域有不同的用途。下面就来看一下在这一部分会有哪些常见的面试题呢?
1、在Java虚拟机中哪一块内存区域不会出现OutOfMemoryError(内存不足错误)的错误?
程序计数器
是唯一不会出现OutOfMemoryError的内存区域。
2、虚拟机栈描述的是什么?存放什么内容/
虚拟机栈描述的是Java方法执行的内存模型,当一个方法被执行时会创建栈帧存入栈内,栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息
。
3、虚拟机栈可能出现哪两种异常,分别会在什么情况下出现?
虚拟机栈可能出现的两种异常是StackOverflowError
(堆栈溢出异常)和OutMemoryError
(内存不足异常)
如果虚拟机栈不可以动态扩展, 当线程请求的栈深度大于虚拟机所允许的深度时,将抛出 StackOverflowError 异常;
如果虚拟机栈可以动态扩展, 当无法申请到足够的内存时,将抛出 OutOfMemoryError 异常。
4、堆的特点是什么?存放什么内容?
堆是Java虚拟机管理的内存中最大的一块
,其目的是存放对象实例,几乎所有的对象都在堆中分配内存。
5、静态变量存放在哪一块内存区域?
静态变量存放在方法区
,
和 Java 堆一样,方法区也是被所有线程共享的内存区域。方法区用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
但是自JDK 1.8以后, 将方法区彻底移除,取而代之的是
元空间
,元空间使用的是直接内存。
6、垃圾回收主要针对Java内存中的哪一个区域?
垃圾回收主要针对Java内存中的堆,
原因是: 程序计数器、虚拟机栈和本地方法栈都是线程私有的,当线程结束时,这些区域的生命周期也结束了,因此不需要过多考虑回收的问题。而堆是虚拟机管理的内存中最大的一块,堆中的内存的分配和回收是动态的,垃圾回收主要关注的是堆空间。
7、方法System.gc的作用是什么?该方法与Runtime类中的方法gc有什么区别和联系?
方法System.gc
的作用是提示 Java 虚拟机进行垃圾回收,该方法被调用之后,由 Java 虚拟机决定是立即回收还是延迟回收。在 System 类中,方法 gc 是静态方法,在 Runtime 类中,方法 gc 是实例方法,方法System.gc
会调用Runtime
类中的 gc 方法,System.gc
等价于 Runtime.getRuntime.gc
。
8、方法finalize在哪个类中定义,以及它的默认实现是什么?该方法的作用是什么?
方法 finalize
在 Object
类中被定义,该方法的默认实现不做任何事。在释放对象占用的内存之前会调用该方法,如果必要,子类应该重写该方法,一般建议在该方法中释放对象持有的资源。
9、判断对象是否可以回收。有哪两种算法?
判断对象是否可以回收的两种算法是“引用计数算法
”和“根搜索算法
”。
10、追问:那么Java使用的是哪一种算法,另一种算法又有什么不足之处呢?
Java使用的是“根搜索算法
”,“引用计数算法”虽然实现简单,判定效率高,但是缺点是无法解决对象之间循环引用的问题,当存在循环引用时,使用引用计数算法会导致无法对循环引用的对象进行回收。
引用计数算法
引用计数算法给每个对象添加引用计数器,用于记录对象被引用的计数,引用计数为 0 的对象即为可回收的对象。虽然引用计数算法的实现简单,判定效率也很高,但是引用计数算法无法解决对象之间循环引用的情况。如果多个对象之间存在循环引用,则这些对象的引用计数永远不为 0,无法被回收。因此 Java 语言没有使用引用计数算法。
根搜索算法
主流的商用程序语言都是使用根搜索算法判断对象是否可回收。根搜索算法的思路是,从若干被称为 GC Roots 的对象开始进行搜索,不能到达的对象即为可回收的对象。
在 Java 中,GC Roots 一般包含下面几种对象:
- 虚拟机栈中引用的对象;
- 本地方法栈中的本地方法引用的对象;
- 方法区中的类静态属性引用的对象;
- 方法区中的常量引用的对象。
11、Java中的四种引用按照引用强度从高到低的顺序依次是什么?
强引用、软引用、弱引用、虚引用
强引用是指在程序代码中普遍存在的引用。垃圾回收器永远不会回收被强引用关联的对象。
软引用描述还有用但并非必需的对象。只有在系统将要发生内存溢出异常时,被软引用关联的对象才会被回收。在 JDK 1.2 之后,提供了 SoftReference 类实现软引用。
弱引用描述非必需的对象,其强度低于软引用。被弱引用关联的对象只能存活到下一次垃圾回收发生之前,当垃圾回收器工作时,被弱引用关联的对象一定会被回收。在 JDK 1.2 之后,提供了 WeakReference 类实现弱引用。
虚引用是最弱的引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被回收时收到一个系统通知。在 JDK 1.2 之后,提供了 PhantomReference 类实现虚引用。
12.新生代和老年代分别适合使用哪种垃圾回收算法?
在新生代中,大多数对象的生命周期都很短,因此适合采用复制算法
;
在老生代中,对象存活率高,因此选用标记-清除算法
或标记-整理算法
。
13、在分配内存空间时,为什么大对象直接在老年代中分配?
将大对象直接在老年代中分配的目的是避免在Eden
区和 Survivor
区之间出现大量内存复制
。
今日总结
今天和大家分享的有关于Java虚拟机的相关内容,但是这一部分内容的理论性特别强,不容易记忆,因此这一部分在面试前看看能记住就行了,但是里面的垃圾回收的几个算法还是要了解的。如“引用计数算法
”、“根搜索算法
”、“标记-清除算法
”、“复制算法
”、“标记-整理算法
”、“分代收集算法
”等。
如果小伙伴们有遇到其他相关的面试题,欢迎在评论区留言提出,我会把大家提出的总结到文章内`, 欢迎小伙伴们一起评论区打卡学习!小伙伴们可也在左方加我好友一起探讨学习!
我是==灰小猿==,我们下期见!
- 点赞
- 收藏
- 关注作者
评论(0)