java 面试知识点笔记(四)垃圾回收 上篇

Wesley13
• 阅读 502

问:对象判定为垃圾的标准?

没有被其他对象引用

问:对象判定为垃圾的算法?

引用计数算法

  • 通过判断对象的引用数量来判断对象是否可以被回收
  • 每个对象实例都有一个引用计数器,被引用则+1,完成引用-1
  • 任何引用计数为0的对象实例可以当垃圾收集的

    优点:执行效率高,程序受影响较小

    缺点:无法检测出循环引用的情况,导致内存泄漏memory leak

可达性分析算法

  • 通过判断对象的引用链是否可达来决定对象是否可以被回收

可以作为GC Root的对象

  • 虚拟机栈中的引用对象(栈帧中的本地变量表)
  • 方法区中的常量引用对象
  • 方法区中的类静态属性引用的对象
  • 本地方法栈中JNI(Native方法)的引用对象
  • 活跃线程的引用对象

问:谈谈你了解的垃圾回收算法?

标记-清除算法(mark and sweep)

java 面试知识点笔记(四)垃圾回收 上篇

  • 标记:从根集合进行扫描,对存活的对象进行标记
  • 清楚:对堆内存从头到尾进行线性遍历,回收不可达对象内存,并把原来标记为可达的标记清除掉

优点:效率高,因为不需要对对象的移动操作。

缺点:碎片化,标记清除之后会留下大量不连续的内存空间,碎片太多可能会导致以后程序运行过程中无法提供连续内存,而不得不进行另一次垃圾回收

复制算法(Copying)

java 面试知识点笔记(四)垃圾回收 上篇

  • 分为对象面和空闲面
  • 对象在对象面上创建
  • 存活的对象从对象面复制到空闲面
  • 将对象面所有对象内存清除

优点:

  • 解决了碎片化的问题 (每次复制到空闲面的对象都是连续排放的)
  • 顺序分配内存,简单高效 (每次直接清理一半的内存空间,所以简单高效)
  • 适用于对象存活率低的场景,比如年轻代(现在成熟的商业虚拟机中都采用这种算法回收年轻代,因为年轻代一般只有10%的对象存活,所以使用这种算法效率还不错)

缺点:在应对对象存活率较高时就有些力不从心了,因为有较多的复制操作,效率将会变低。而且不想浪费额外的50%空间,就需要更多的空间进行担保,因为需要应对所有对象都100%存活的极端情况,所以老年代一般不能选用这种算法。

标记-整理算法(Compacting)

java 面试知识点笔记(四)垃圾回收 上篇

  • 标记:从根集合进行扫描,对存活的对象进行标记
  • 清除:移动所有存活的对象,且按照内存地址次序一次排序,然后将末端内存地址以后的内存全部回收

优点:解决了内存碎片化的问题,清理之后内存是连续的,也不用设置两块内存互换,适用于存活率较高的场景

缺点:需要移动标记存活的对象,成本较高

分代收集算法(Generational Collector) 现在主流的GC算法

  • 垃圾回收算法的组合拳
  • 按照对象生命周期的不同划分区域以采用不同的垃圾回收算法
  • 目的:提高JVM的回收效率

java 面试知识点笔记(四)垃圾回收 上篇 java 面试知识点笔记(四)垃圾回收 上篇

JDK8之后没有永久代,但是年轻代、老年代都保留了下来,年轻代使用的是复制算法,老年代使用的标记整理算法

问:分代收集算法的GC分几种?

  • Minor GC (发生在年轻代中的垃圾收集工作,使用复制算法。年轻代是所有java对象出生的地方,新对象一般存活率较低,所以MinorGC比较频繁)
  • Full GC

 

年轻代:

  • Eden区(就是伊甸园,代表这人类的起源,新对象存放的区域,如果eden区放不下新对象,也有可能会放在survivor区甚至是老年代中)
  • 两个Survivor区(幸存者区,from区和to区,这两个区也不是固定的,会随着垃圾回收而相互转换)

java 面试知识点笔记(四)垃圾回收 上篇

默认是8:1:1的比例分配,垃圾清理时会将eden和from区的存活对象一次性复制到to区,to区不够用的时候需要老年代做担保

年轻代垃圾回收的过程演示:

java 面试知识点笔记(四)垃圾回收 上篇 java 面试知识点笔记(四)垃圾回收 上篇 java 面试知识点笔记(四)垃圾回收 上篇

每次存活就会标记+1,默认是15岁,也可以设置-XX:MaxTenuringThreshold设置最大年龄限制,到达限制就会进入老年代,当然如果eden或者survivor装不下也会进入老年代

对象如何晋升为老年代:

  • 经历一定Minor次数依然存活的对象
  • Survivor区放不下的对象
  • 新生成的大对象(可以设置-XX:+PretenuerSizeThreshold设置大对象大小,超过这个大小的大对象会直接放入老年代)

常用的调优参数:

  • -XX:SurvivorRatio:Eden和Survivor的比值,默认8:1
  • -XX:NewRatio:老年代和年轻代内存大小比例,比如2表示老年代是年轻代的2倍

老年代:存放生命周期较长的对象

  • 标记-清理算法
  • 标记-整理算法

一般会伴随着新生代的回收及整个堆的回收(FullGC和MajorGC,FullGC比MinorGC慢,但执行频率低)

问:出发FullGC的条件?

  1. 老年代空间不足(最好不要创建太大对象)
  2. 永久代空间不足(JDK7以前的版本,这也是JDK8使用元空间替代永久代的原因,降低了FullGC的频率)
  3. CMS GC时出现promotion failed ,concurrent mode failure(注意日志里是否出现这两个情况,这两种情况很容易触发FullGC)
  4. Minor GC 晋升到老年代的平均大小大于老年代剩余空间(hotspot在进行MinorGC做了个统计,如果晋升到老年代的平均大小大于老年代剩余空间就直接触发Full GC)
  5. 调用System.gc()(这只是程序提醒虚拟机,码农希望这里进行一下回收,但回不回收还是要看JVM)
  6. 使用RMI来进行RPC或者管理JDK应用,默认每小时执行一次FullGC
点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
九路 九路
3年前
4 Java 如何判定是否存活或者死亡
在堆中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事就是要确定这些对象之中哪些还活着,哪些对象已经死去.判断对象是否已经死亡有以下几种算法:引用计数法算法定义:给对象中添加一个引用计数器,当有一个地方引用时,计数器加1,引用失效时,就减1,当对象的引用计数器为0时,对象就是不可再被使用的.特点:JAVA虚拟机中很少使用这
xiguaapp xiguaapp
3年前
垃圾回收机制
GC标记算法对象被判定为垃圾的标准:没有被其他对象引用引用计数算法:判断对象的引用数量:通过判断对象的引用数量来决定对象是否可以被回收每个对象实例都有一个引用计数器,被引用则1,完成引用则1任何引用计数为0的对象实例可以被当做垃圾收集优点:执行效率高,程序执行受影响较小。
Stella981 Stella981
3年前
JVM学习第二天
引用计数算法对象中添加一个引用计数,一个地方引用它时,计数器值就加1,当引用失效时,计数器值就减一两对象互相引用,就会造成死循环,无法回收可达性分析算法通过GCRoots作为起点,向下搜索,到达不了的对象,即证明对象不可用GCRoots包括:虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用
Stella981 Stella981
3年前
JVM笔记整理
不对之处还望指正。垃圾回收1\.如何判断对象是垃圾对象?引用计数法在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值1,当引用失效时,则值1.此方式不能解决循环引用的问题。验证添加gc日志,\_005GC.javaverbose:gc
Stella981 Stella981
3年前
JVM垃圾回收算法
一、如何判断对象时候需要回收1.引用计数法        给对象添加一个引用计数器,每当有一个地方引用它,计数器加1;引用失效时,计数器减1。计数器为0的对象就表示不可用。      优点:效率高,实现简单。      缺点:对象间如果存在循环引用的情况,就会导致计数器不可能为0,计数器无法通知GC进行回收。2.可达性分析算法
Wesley13 Wesley13
3年前
PHP垃圾回收机制
php5.3之前使用的垃圾回收机制是单纯的“引用计数”,也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器1;当变量引用撤掉后,计数器1;当计数器0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。“引用计数”存在问题,就是当两个或多个对象互相引用形成环状后,内存对象的计数器则不会消减为0;这时候,这一组内存对象已经
Stella981 Stella981
3年前
JVM调优总结(三)
可以从不同的的角度去划分垃圾回收算法:按照基本回收策略分引用计数(ReferenceCounting):比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。标记清除(MarkSweep):
Stella981 Stella981
3年前
JVM垃圾回收机制
引用计数法:当给对象添加一个引用计数器,每当有一个地方引用这个对象时计数器值就1;引用失效时,计数器值就1;任何时刻计数器为0的对象就是不可能在被使用。优点:引用计数收集器可以很快地执行,交织在程序运行中。缺点:无法检测出循环引用。例如:MyObjectobject1newMyObject();MyObjectobject2
Stella981 Stella981
3年前
JVM03
前言今天来学习下与JVM垃圾收集机制相关的一些基本概念。如何判断对象是否存活垃圾收集器首要的任务的任务就是判断哪些对象是存活的,哪些对象已经死去了(这里死去的意思是对象不再被任何途径使用)。引用计数算法引用计数算法是在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器