2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)前言为什么需要垃圾回收首先我们来聊聊为什么会需要垃圾回收,假设我们不进行垃圾回收会造成什么后果,我们举一个简单的例子我们住在一个房子里面,我们每天都在里面生活,然后垃圾都丢在房子里面,又不打扫,最后房子都是垃圾我们是不是就没法住下去了。所以JVM垃圾回收机制也是一样的,当我们创建的对象占据堆空间要满了的的时候我们就对他进行垃圾回收,注意java的垃圾回收是不定时的,c语言的是需要去调用垃圾回收方法刚刚也说到上面举的例子也说到假设一个房子都被垃圾堆满了那么我们没法住人了那么我们是不是会告

大家好,又见面了,我是你们的朋友全栈君。

前言

为什么需要垃圾回收

  • 首先我们来聊聊为什么会需要垃圾回收,假设我们不进行垃圾回收会造成什么后果,我们举一个简单的例子
  • 我们住在一个房子里面,我们每天都在里面生活,然后垃圾都丢在房子里面,又不打扫,最后房子都是垃圾 我们是不是就没法住下去了。
  • 所以JVM垃圾回收机制也是一样的,当我们创建的对象占据堆空间要满了的的时候我们就对他进行垃圾回收,注意java的垃圾回收是不定时的,c语言的是需要去调用垃圾回收方法
  • 刚刚也说到 上面举的例子也说到 假设一个房子都被垃圾堆满了 那么我们没法住人了 那么我们是不是会告诉别人这个房子没法住人了 而java也是如此当我们堆空间满了的时候 此时它就会抛出异常OutOfMemoryError(简称OOM)

什么地方需要进行垃圾回收

刚刚我们说了为什么要回收垃圾,和什么是OOM那么我们下面就给大家介绍,我们JVM中什么地方需要进行垃圾回收。

垃圾回收要考虑的点

1)是否会产生垃圾
2)哪些内存需要回收
3)什么时候回收
4)如何对他进行回收

2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

程序计数器
jvm中唯一 一个不需要垃圾回收的地方。
栈 本地方法栈
这个地方会因为栈帧存满了导致内存溢出,所以需要垃圾回收
方法区(元空间)
这个地方也需要进行垃圾回收

这个地方是我们垃圾回收最频繁的地方,我们几乎我们所有的对象都存储在堆中,也是我们今天要着重讲的地方

堆GC

堆,可能大家都不陌生,可是好像又距离我们很远,今天它来了
2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

从上面的图我们可以看出 ,我们的堆空间被主要被划分为了二块区域 ,新生代 ,老年代 java堆是我们JVM中管理区域最大的一块, java堆是一个线程共享的区域 ,在虚拟机启动时创建 ,几乎所有的对象都在此分配, java虚拟机规范中有过描述,所有的实例对象以及数组都在堆中进行分配内存, 但目前因为JTI编译器的发展,和逃逸分析技术的逐渐完善,在堆中分配对象也不是那么的绝对了。
堆的内存在物理上可以是不连续的,但是在逻辑上是即可。

新生代

  • 我们对象的创建到结束,几乎是”朝生夕死“的一个过程差不多90%的对象都在新生代被回收了,所以新生代的gc也是发生最为频繁的一个区域。新生代产生gc我们称为Y-GC
  • 每产生一次y-gc我们对象的年龄就加一岁,直到15岁后进入老年代。当然这是正常情况,那么有没有特殊情况勒当然有

空间担保

  • 当我们创建的对象大于Eden的时候,此时怎么办,此时他会先产生一次Y-GC如果还是无法存储下新创建的对象,那么我们就会通过空间担保策略进入老年代。
  • 还有一种情况,对象创建也会直接进入老年代,当我们的Surivivor区满了的时候,此时它不会主动产生gc只会依赖于Eden,但我们的对象又不能被抛弃,所以它也被分配到了老年代
  • 当然我们实际开发工作中需要尽量的去避免这种情况的诞生

动态年龄

  • 什么是动态年龄勒,这是堆中的另一个,担保策略了,它会去判断我们Surivivor的区中,相同年龄的对象大于Surivivor区一半的时候,那么他就会判定此时这些对象已经能够很好的存活了,所以他们就集体被丢到老年代了

对象如何分配内存

2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

老年代

  • 我们老年代存放的都是一些老对象了,大对象,都是存活时间较长的对象这里一般很少产生FGC这里一旦产生FGC那么所产生GC的耗时将会是YGC的10倍时耗,而我们老年代快要存满时进入了一个对象,这时会产生一次FGC如果GC结束后,还是无法存放对象的话此时就会报OOM异常。

垃圾回收算法

分代算法

分代算法,其实也就是将我们堆空间划分为了一个个不同的区域,新生代,老年代,不让它回收的时候对整个堆进行一个回收。减少GC所停顿的时间,我们称之为STW (Stop The World),假设我们堆整个堆进行垃圾回收,是不是每次都需要去把整个堆的垃圾标记一次,非常的那么用户线程停止的时间就非常长,你想一下,假如你的电脑每使用1个小时就卡10秒,那么你是不是非常操蛋。

标记清除

算法执行过程

堆空间垃圾清理前
2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

垃圾清除后
2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

算法介绍
标记清除是最开始jvm选择的一种垃圾回收算法,这个算法就和他的名字一样,分为标记,和清除二个过程,首先他会标记所有需要回收的对象,标记结束后对标记的对象进行一个垃圾回收。
缺点
这种方式会有什么缺点呢!它会导致内存空间的浪费,产生大佬不连续的内存碎片,当我们需要一个连续的内存空间存放大对象的时候,因为连续的内存空间不够,导致我们不得又产生一次GC,提高了我们GC产生的频率。

标记整理

算法执行过程
2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

算法介绍
标记整理,的执行过程,于标记清除相反,标记清除是标记需要回收的对象,而标记整理却是标记存活的对象,然后把他们全部向一段进行位移,然后清除端边界以外的所有对象。
适用范围
老年代垃圾回收

复制算法

算法执行过程
2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

算法介绍
复制算法也是在标记清除上的一个改进,它弥补了标记清除出现大量不连续内存碎片的缺点。它将一个可用的内存空间划分为大小相等的二块区域,每次只使用其中一块区域,当这块区域用完了就把存活的对象放到,另一块空着的区域区,然后把自己清除干净,变成一块空着的区域。这样就解决了内存碎片的问题
缺点
那么这样的算法是不是太过于苛刻了,每次都需要一块空着的区域用于存放对象,牺牲掉了大量的内存。
适用范围
新生代Surivivor区域

堆中对象内存的分配策略

指针碰撞

这种分配方式其实是复制算法,标记整理中的携带的一种对象分配策略,我们如何区分什么是用过的,什么是没用过的,这时我们通过一个指针,作为一个分界点指示器,那所需要分配的内存,就仅仅是把指示器指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为”指针碰撞”(Bump the Pointer)。

空闲列表

空闲是标记清除中对对象分配的一个策略,因为标记清除中我们的内存划分的随机的,已使用内存和未使用内存相互交错,那么我们如何把他们关联起来,虚拟机针对这种交错的内存维护了一个列表,记录哪些内存块是可用的,在分配的时候找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式成为”空闲列表”(Free List)。

OOM异常

其实OOM在上面介绍了堆内存的划分和收集过程中,大家也应该对它有了一定的认识了,OOM异常是发生在老年代Old中的一个异常,当我们老年代中无法在存放对象的时候,就会报OOM内存溢出异常

public class HeapOomError {
    public static void main(String[] args) {
        List<byte[]> list =new ArrayList<>();
        int i=0;
        while (true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e){
                e.printStackTrace();
            }
            list.add(new byte[5 * 1024 * 1024]);
            //System.out.println("count is:"+(++i));
        }
    }
}

设置堆空间的大小
2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

最后我们得到的结果如下
2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

小结

总而言之我们需要的优化的GC的损耗和避免内存溢出的出现,从而提高我用户良好使用体验。

总结

最后我为大家准备了Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。点击这里备注csdn,自行下载!只有技术过硬,在哪儿都不愁就业,“万般带不去,唯有业随身”学习本来就不是在课堂那几年说了算,而是在人生的旅途中不间断的事情。
2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141649.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 大数运算的算法设计和C++实现[通俗易懂]

    大数运算的算法设计和C++实现[通俗易懂]1、背景工作中遇到过需要进行极大数据的存储和运算的场景,当时使用Python解决了这个问题,在Python中,整数没有位数限制,使用起来很方便。但是当程序主体使用C/C++实现时,就比较麻烦。所以考

    2022年7月3日
    24
  • 图像分割必备知识点 | Unet详解 理论+ 代码

    图像分割必备知识点 | Unet详解 理论+ 代码文章转自:微信公众号【机器学习炼丹术】。文章转载或者交流联系作者微信:cyx645016617Unet其实挺简单的,所以今天的文章并不会很长。喜欢的话可以参与文中的讨论、在文章末尾点赞、在看点一下呗。0概述语义分割(SemanticSegmentation)是图像处理和机器视觉一个重要分支。与分类任务不同,语义分割需要判断图像每个像素点的类别,进行精确分割。语义分割目前在自动驾驶、自动抠图、医疗影像等领域有着比较广泛的应用。上图为自动驾驶中的移动分割任务的分割结果,可以从一张图片中有效的识别

    2022年6月16日
    54
  • PO模式介绍

    PO模式介绍目标1.深入理解PO模式的思想2.熟练掌握PO模式的分层思想1.存在的问题在做UI自动化时定位元素特别依赖页面,一旦页面发生变更就不得不跟着去修改定位元素的代码。举例:假设要对一个元素进行点击操作,而且会经常对该元素进行操作,那么你就可能会编写多处如下代码 1 driver.find_element_by_id(“login-btn”…

    2022年4月30日
    106
  • Vuex中的mapGetters

    Vuex中的mapGettersmapGetters辅助函数仅仅是将store中的getter映射到局部计算属性语法是mapGetters([‘language’,’token‘])参数是个数组,数组里是你想要映射的getters里的值import{mapGetters}from’vuex’;computed:{//利用使用对象展开运算符将getter混入computed…

    2022年6月12日
    44
  • OA系统权限管理设计(转载)

    OA系统权限管理设计(转载)

    2021年12月6日
    35
  • JDK安装与配置详细图文教程

    JDK安装与配置详细图文教程JDK安装与配置详细图文教程   目的:本人健忘,以后难免会重装系统啥的,软件卸了装是常有的事,特此写此详细教程,一是方便自己以后重装的时候可以看看;二是如果有某位初学者有幸光临,也可以给一点参照。下面我会从JDK的下载、安装、环境变量的配置和其中的一些问题进行详细说明,Letgo!一、下载JDK是个免费的东东,所以大家不要去百度啥激活成功教程版了,直接去官网下载最新版本吧,比较安全,官网

    2022年7月8日
    16

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号