粉丝4182获赞2.6万




关于 gm 中一次完整的 gc 流程,怎么样的对象是如何晋升到老年代的?这个问题在面试过程中的频率非常高,今天正好有空给大家分享一下这个问题的回答思路。如果需要文字版本和完整的大厂面试手册,可以在评论区的置顶中去领取。 关于这个问题,我们可以先描述加号对于内存的划分,再解释 manel g c, 复尔 g c, 最后再描述他们之间的转化流程。 nice 以下是我的回答思路。加尔堆内存是由新生代和老年代组成,其中啊,新生代又包括一等区和 cyv 区。一个新的对象首先会分配在一等区, 如果是大对象会直接进入到老年代。当一等区空间满了以后,基本会触发一次 manen 七 c 用来回收一等区的内存。一等区存活下来,对象会转移到 c yy 区。如果对象 在一等区出生并经过一次 man g c 以后仍然存活,那么这个时候这个对象的 g c 年龄会设置成一。每熬过一次 man g c, 该对象的 g c 年龄都会进行累加。 如果超过默认的 gc 次数十五次,这个对象就会转移到老年代。当老年代满了以后无法容纳更多对象的时候,就会触发富尔 gc。 富尔 gc 呢,会清理整个堆内存,包括年轻代,老年代。 需要注意的是,在进行副耳 gc 之前啊,通常会先进行一次样 gc, 你尽可能的清理掉一等区和十万个区的垃圾对象,以减少副耳 gc 的压力和耗时。 在样 gc 以后,存活对象将会被复制到什么样区或者 out 区,而一的区呢?会被完全清空,等待下一次的对象分配。好的,今天的分享就到这里,感谢大家的关注和点赞,如果你还有更多好的问题可以在评论区给我留言,我们下次再见,拜拜!

谈谈你对 d v m 中主要的积虽算法的一个理解啊,那么这道题呢,最主要的呢,它考核的是 d v m 的一个结构和 内存管理的一些机制,所以呢这个 g c 呢,其实是 j v m 里面比较重要的一种设计啊。 g c 它主要的作用呢就是说垃圾回收,它就会涉及到一些垃圾回收的一些机制,一些策略,或者说一些看法。一般来说呢,我们在 j v m 中呢有三种回收的算法,一般分别是标记清除、 标记复制和标记整理,那么这三种算法呢,其实就是一种内存管理方式啊,我给大家简单介绍一下他每种算法的一个核心的原理 及他的一个具体的操作啊。首先呢是标记清除算法,那么标记清除算法呢,就相当于是将存活的对象先打上标记,那么没有标记的对象呢,就我们需要被回收的垃圾对象,那么这些垃 垃圾对象呢,就是如果说没有被标记出来的话,什么垃圾回收器直接就会对他进行回收,那么一般情况下呢,就因为我们去判断这个对象要不要回收呢,基本上呢就是通过一种叫做可达线分析去做判断啊,也就是说这个对象他一分析他发现,哎,这对象是可达, 就说他的饮用依旧还被别的对象在持有,并且在使用,这个时候呢,这个对象是不能被回收的啊, 不能被回收呢,我就会给他打上标记,那么这些对象在内存呢还存在,但是呢没有任何人引用他或者是一个空指针,这个时候呢,我们就会将他去回收掉,所以呢我们垃圾回收器呢,只能回收这些不可达的对象,那我们的这个标记清除方法呢,就是说 当内存里面这些存活的不能回收的对象呢,打上标记,那么没有标记的对象他就直接回收了。根据毕生所学,给大家研制了一份嘉华程序员的一个求职突击手, 包含简历模板,优势突击押题一周的一个技术提升以及嘉娃提升的一个完整学习路线。领取方式呢,在我视频主页一册在手,保你高薪无忧 标志肤计算完了,就是他会把内向的内存呢分为两个等份,那么呢每次呢我们只使用一份啊,也就说只使用内存一半,等到正在使用的这部分呢,快满的时候,他就会把正在存活的啊就是 答的对象给他标记出来,就把他移到另外一部分闲置的空间中,这个时候呢,那留在另一部分对象呢就会被垃圾回收,那么这个时候呢,原来闲置的空间就会变成一个 使用中的状态,那么原来使用中的空间呢,就会显示出来继续使用,这样的话呢,来回反复的切的话,就能够完成一次完整的一个技术的过程。那么随着分配的这个对象又满了后呢,还要把原来对象呢又拿出来,可以继续 就能够迁移,不用花的去做这么一个动作,这就是标记复制算法,那么最后一种就是标记整理算法,标记整理算法呢,就是他会先将存货对象标记出来,把所有的存货的对象直接整理到内存空间的另一段,而没有标记的对象呢,直 先去把它覆盖掉或者是释放掉,这种方式呢来进行一个垃圾回收,那么这三种垃圾回收算法呢,都各自有他的一个应用场景以及他们的优缺点。那么首先来看我们讲到的标记清除算法,那么标记清除算法呢,他主要的缺点就是会产生比较多的一些内存的碎片,而这些内存碎片呢, 随着我们系统运行的一个推移,系统运行时间长了以后,久了以后呢,就可能没办法去大量的去分配一些连续的空间,就会导致更加频繁的去触发机芯啊,因为机芯的触发呢,只有是当我们的这个内存不够用的 之后,他才会去触发的。然后呢这个标记复制算法呢,他的主要的缺点就是会导致我们在实际的使用的内存空间就是只有一半,也就是只有百分之五十, 另外的百分之五十呢,大部分时间是闲置的,所以呢他是比较浪费空间。那如果说出现这种啊,要大量复制对象的话呢,这个垃圾回收的这个耗时就比较长了, 这种方法呢就更加适合去处理一些,这个存活对象少,然后呢垃圾对象比较多的一个场景,那么最后就是标记整理,标记整理呢,他的本质就是去和标记清除刷法呢差不多,只不过说标记整理呢,他多了一个动作,就是把存活的对象呢,就是一 到一起,也就是去移到一个连续的空间,他相当是增加一个迁移的一个动作,因为加我的对象呢,基本上都是一些临时对象,所以呢很快就会被回收,这个时候呢,我们 j o m 内存呢,他也会做一些分代的一些设计啊,那么根据对象在内存中存货的时间,他又分为年轻贷、老年贷和永久贷。那么年轻贷呢,采用的是标记复制算法,也就是说在每次复制的时候,存货下来的这个对象呢,会很少,老年贷呢,一般会经历过几次的 c 啊,最后认为他可能还会继续一直存活下去,所以呢,他就不太适合就采用这种标记复制算法。老年代呢,采用的是标记清除算法,那比如说像 cms 这种活动器就采用的是标记清除的方式,那永久的呢?永久的的话就 一直会存活啊,也就是说他只有在触发富尔机器的时候才会被回收,所以永久在呢,他是对象创建过多的,这个情况下,比较容易出现这种内存溢出。那么最典型的产品就是比如说结实 页面,如果说页面比较多的情况下呢,就很容易出现一些永久在的一个内存一出,总结一下哈,所以说呢,精心算法呢,它代表的是我们的这个 gam 对象回收的一种策略,所以这个时候我们 不同的垃圾回收竟然会选择不同的这个机器的算法呢,实现垃圾的回收,所以呢什么的算法呢,更加符合当前的这个对我们的开放员来说呢,这种判断呢,其实也是一种比较基础的能力。

jvm 发现我们的服务的内存有频繁 gc, 怎么排查?什么叫频繁 gc 啊?就是对象创建了,然后立马要回收了, 又创建了,立马又回收了,是这意思吧?那怎么排查呢?首先用 top 排序,然后再用 jsteng 进行分析,对吧?段谱对文件分析,首先我们可以去通过这个结果自身的命令哈,就找到他的一个问题,发生的节点在哪里啊? 但是呢,具体的原因呢,可能有很多种,第一种呢,可能就是程序出现这种循环创建的对象,然后创建完对象呢,这个对象又不是全局的,他是一个临时变量,就在循环里面溜出来, 循环结束之后,哎,没了,而且这个循环呢,有可能是一个死循环啊,就一直在创建,一直在回收,所以就导致了出现这种顶翻的 gc。 因为 cc 的出现的情况呢,他只有一个原因哈,就是他要去检测你这个对象是不可达,如果说你这个对象不可达了,他才会回收啊,那么一般来说可达线分析的话呢,我们就可以去通过这个界外门的这个监控啊,可以去看得到,像这里输的是平方计时段,其也就是说 他的这个不断的在产生这种不可达的变量,或者这种对象,什么情况下才能产生这种不可达的这个对象呢?基本上就是一些临时的变量,在衣服里面声明呢,在雪花里面声明呢, 或者在某一个代码框里面声明的,这些都是属于临时的对象啊,那么这项对象之后,只要你运行完之后,在外面之后就防不了了,所以他就是 不可答了啊,这个本质原因就是找到这里就行了啊。那么具体的话代码呢?我们只要分析到知道这个原因之后呢,你就可以有具体的一个解决方案,解决思路啊,这都 ok 了啊。

另外一道阿里伊面的面试题,请说一下 jbm 中哪些是共享区,哪些可以作为 b c 入?他实际上这个题目应该是两道题目啊,就是这边 m 中哪些是共享区,哪些可以作为 g c 入的,所以说啊, 在回答这个面试题的时候,那肯定要分为两步。好,那么呃,大家可以先看一下周瑜老师我给到大家的答案啊,我这边也是写成了两点,第一点就是你首先要答一下哪些是共享区,那么我这边还给大家呃配了一个图啊,那么看到这个图带其实就一目了然, 这个东西,呃,就是如果说对这边比较熟的同学,应该算是比较简单的一道题目了。好,那么当然你答的时候你就不要观光只答共享区啊,你可以整个这边 m 里面的所有的 区域你都可以说一下,然后再去说哪些是共享区,哪些是每个县城独有的,所以大家可以看一下,就是运行时数据区里面有方法去一堆去 连接上,包括本地方法上,然后包括程序计数器,然后除开运行运行时数据区之外,我们还有执行引擎,还有本地库接口,还有本地方法,那么像我们的方法去和对,这就是我们说的所有现成共享的,当然方法去里面存的又是类,对不对? 堆里面存的又是对象,那肯定是所有现成共享的,那么像我们说的账,或者说,呃,另外一个称呼就是虚拟机账,包括本地方法账,包括程序计数器,这都 都是跟每个县城在执行代码的过程中间会用到这三个区域,所以说这三个区域是每个县城独有的啊,就这么回答基本上就 ok。 好,那么我我们再来看一下,哎,就第二个题目是哪些?呃,东西可以作为 g c 入场啊?那么首先你肯定要解释什么是 g c 啊? g c 入场其实就是 j v m, 他在进行垃圾回收的时候,我们一个 j v m 里面,比如说这个堆里面我们会 有很多的对象,那么垃圾回收其实就是你最关键的,你最终的最终的目的就是要去找到什么是垃圾,那就要找到垃圾对象。但是什么是垃圾对象,其实就是那些没有被 引用的对象,最是没有被引用的对象就是目前堆里面有一个对象,但是没有人再用他了,所以这个对象肯定就没有用,所以我们就需要把这就是我们所要找的垃圾对象。那么但是一个堆里面会有很多很多的对象,那你要去找那些没有被用到的对象,这是比较复杂的 啊,是比较耗时的。所以呢啊,其实应该反过来就是我们应该先去找那些非垃圾对象啊,也就是正常在在被使用的对象。那么我们怎么去找到那些正常在被使用的对象呢?哎, 其实就需要从某些根开始去找,而这些根其实就是路上,而这些根他就是一个一个根,我们有这个根,我们一步一步去找,其实在这个呃 引用的路径上面,我们就可以找到很多很多正常的对象,而在这个路径上面的那些对象其实就是正在被用的。哎,至少你是从这个根里沿着这个 跟,然后去看他用到了哪些对象,那么这些对象他又用到了另外的哪些对象?那么这些对象就是正常对象,当我们把这个堆里面的正常对象都找出来之后,那么剩下的其他对象就是我们说的垃圾对象,就需要被回收, 所以我们需要 cc 入他。那么什么是根呢?根其实有一个很明显的特征,就是他只会去引用其他对象,而不会被其他对象引用啊, 这是一个根吗?就像我们阿茶树里面的根,节点他只有指节点,他不会呃,有负节点,所以就是类似的。那么像我们通常说的上里面的本地变量,就是你在一个方法中间,你你所写的一个局部变量啊,就是本地变量,那么啊,他基本上这个局部变量他没有别人在,就是不会有其他对象在 用,这个变量基本上就是呃,这个变量会去引用其他对象,让方法去中解金台变量,本地方法账中的变量正在运行的现成,特别是这个,对吧?我们的代码肯定都是现成在运行,所以,呃,我们可以最正常的情况,我们可以根据这四个东西啊,根据这四个东西我们就会 可以把它作为 g 的 g s elot, 然后去找到正常对象,从而找到垃圾对象,这是我们的 g g c ltot。 所以, 但是在面试的过程中间,哎,你可以不像这位老师我这么啰嗦,可以说这么多啊,你就回答的简洁一点,其实就 ok 了,因为啊,这个问题啊本身还是不是那么难啊。那么就是关于这个给大家讲一下。

生产环境中 j v m。 如何合理的监控 g c 情况?在生产环境中啊,合理的收集分析、监控 j v m 的 j c 信息是非常重要的啊,它可以帮助我们监控和优化应用程序的内存使用情况, 及时的发现并且解决一些潜在的性能问题。但是同时呢,咱们也不能占用太多的资源,避免影响咱们系统的性能。首先自然是启动项目的时候,咱们要设置好打印 j c 日志的信息,比如这个 pro n 的 j c 或者普润的 j c details, 或者普润的 j c details tampa 等等这样的一个参数,指定好是要简要的信息还是详细的信息, 是否要打印认证的时间,是否要打印 jc 前后堆内存的详细信息等等。那咱们可以根据情况调整 jc 日志的级别和这种详细程度,那比较低的日志级别呢,可以减少日志数量的大小,减, 减少对于咱们程序性能的影响。还有呢,就是要控制好 j c 日志文件的大小,避免过大,那过大的日志文件呢,它的这个占用的磁盘空间还是比较大的。再有就是上各种分析工具了,咱们可以更好地去分析 j c。 日志的信息,比如像这个 j c viewn 或者是这个 j c e z 这种工具来分析, 呃,可以更好地理解 j c 行为和优化内存的使用。或者也可以上这种普罗米修斯这样的一个监控工具,咱们可以实时监测 j v m 的 j c 情况,定期分析 j c 的情况。 总之呢,要合理的控制好 jc 日志打印的一个详细程度,避免咱们生成过多的日志,甚至划分好 jc 日志的这种磁盘,避免影响咱们的这个 io 性能。再有的话就是定期删除那种远古的日志信息,避免占用太多的磁盘空间,哈哈哈哈,哎呀,腰疼。

自三发布渣吧语言以来,开始使用 gc 技术来进行内存自动管理,避免了手动管理带来的悬挂之针干恶零喷头问题,很大程度上提升了开发效率,从此 gc 技术也一举成名。 gcc 有着非常悠久的历史,一九六零年,有着 leads 支付和人工智能支付制称的 giant mccarcy 就在论文中发布了 gc 算法。六十年以来, gc 技术的发展也突飞猛进,但不管是多么前沿的收集企业,都是基于三种基本算法的组合或应用, 也就是说, gc 要解决的根本问题,这么多年一直都没有变过。笔者认为,在不太远的将来, gc 技术依然不会过时。比起日新月异的新技术, gc 这门古典技术更值得我们学习。那么, gc 问题处理能力能不能系统性掌握?一些 影响因素都是互为因果的问题,该怎么分析?比如一个服务 rt 突然上涨,由 gc 耗时增大,现成 black 增多, 滥查询增多, cbu 负载高四个表象到底哪个是诱因?如何判断 gc 有没有问题?使用 cns 有哪些常见问题?如何判断根因是什么?如何解决或避免这些问题?