GC相关的

简介: GC相关的

1、判断对象是否为垃圾的算法

  • 引用计数算法
  • 可达性分析算法

引用计数算法

判断的标准:

通过判断对象的引用数量来决定对象是否可以被回收。

每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1。

任何引用计数为0的对象实例可以被当作垃圾收集。

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

缺点: 无法检测岀循环引用的情况,导致内存泄露

可达性算法:

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

可以用作GC Root的对象?

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

2、垃圾回收算法

标记—清除算法(Mark and Sweep)

标记: 从根集合进行扫描,对存活的对象进行标记

清除: 对堆内存从头到尾进行线性遍历,回收不可达对象内存

缺点: 会导致碎片化。

复制算法(Copying)

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

优点:

  • 解决碎片化问题
  • 顶序分配内存,简单高效
  • 适用于对象存活率低的场景

标记—整理算法(Compacting)(老年代)

标记:从根集合进行扫描,对存活的对象进行标记。

清除:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。

优点:

  • 避免内存的不连续行
  • 不用设置两块内存互换
  • 适用于存活率高的场景

分代收集算法(Generational Conllector)

垃圾回收算法的组合拳

按照对象生命周期的不同划分区域以采用不同的垃圾回收算法

目的:提高JVM的回收效率

GC的分类:

Minor GC:(新生代清除算法)

Full GC:(老年代清除算法)

  • Minor GC 是清除新生代。
  • Major GC 是清理永久代。
  • Full GC 是清理整个堆空间—包括年轻代和永久代。

当达到15岁以后,会存到老年代,或者Eden区和Survivor装不下,也会到老年代

对象如何晋升到老年代

  • 经历一定 Minor次数依然存活的对象
  • Survivor区中存放不下的对象

新生成的大对象(-XX+ Pretenuer Size threshold)(达到15岁以后)

—XX:Survivorratio:Eden和 Surviⅳor的比值,默认8:1。

—XX:Newratio:老年代和年轻代内存大小的比例。

—XX:MaxTenuringThreshold:对象从年轻代晋升到老生代经过GC次数的最大阈值。

老年代:(存放声明周期较长的对象)

使用算法:

标记—清理算法

标记—整理算法

对整个堆内存进行垃圾回收:

Full GC 和Major GC

Full GC比 Minor GC慢,10倍左右,但执行频率低

触发Full GC的条件

  • 老年代空间不足。
  • 永久代空间不足。
  • CMS GC时出现 promotion failed,concurrent mode failure
  • Minor GC晋升到老年代的平均大小大于老年代的剩余空间
  • 调用 System.gc()
  • 使用RMI来进行RPC或管理的JDK应用,每小时执行1次Full GC

3、分代收集算法(Generational Collector)

Stop-the-World(停止服务)

  • JVM由于要执行GC而停止了应用程序的执行
  • 任何一种GC算法中都会发生
  • 多数GC优化通过减少stop-the-world发生的时间来提高程序性能

Safepoint(安全位置)

  • 分析过程中对象引用关系不会发生变化的点。
  • 产生 Safepoint的地方:方法调用;循环跳转;异常跳转等。
  • 安全点数量得适中。

常见的垃圾收集器

JVM的运行模式:

Server:重量级虚拟机,启动慢,但是启动后快。

Client:轻量级虚拟机,奇动快,但是启动后慢。

java -version

垃圾收集器之间的联系

年轻代常见的垃圾收集器

Seria收集器(-XX:+ Use SerialGC,复制算法)

单线程收集,进行垃圾收集时,必须暂停所有工作线程。

简单高效,Client模式下默认的年轻代收集器。

几十至几百兆基本需要几十到几百毫秒。可以忍受。

ParDew收集器(-XX+ Use ParNewGC,复制算法)

多线程收集,其余的行为、特点和 Seria收集器一样。

单核执行效率不如 Serial,在多核下执行才有优势。

开启的线程数和你的CPU核数相关。

Parallel Scavenge收集器(-XX:+ UseParallelgc,复制算法)

比起关注用户线程停顿时间,更关注系统的吞吐量。

在多核下执行才有优势,Server模式下默认的年轻代收集器。

吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)

4、老年代常见的垃圾收集器

Serial Old收集器(-XX:+UseSerialOldGC,标记—整理算法)

  • 单线程收集,进行垃圾收集时,必须暂停所有工作线程。
  • 简单高效,Client模式下默认的老年代收集器。

Parallel old收集器(-XX:+UseParalleloldgC,标记-整理算法)

多线程,吞吐量优先。

CMS收集器(-XX+ Use ConcMarkSweepGC,标记清除算法)(最主要的)

几乎能与用户线程同时工作(减少停顿时间)

回收的步骤:(1.4会让JVM停止工作)

  1. 初始标记:stop-the-world
  2. 并发标记:并发追溯标记,程序不会停顿
  3. 并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象
  4. 重新标记:暂停虚拟机,扫描CMS堆中的剩余对象
  5. 并发淸理:清理垃圾对象,程序不会停顿
  6. 并发重置:重置CMS收集器的数据结构

CMS有3个明显的缺点:

  1. CMS收集器对CPU资源非常敏感。
  2. CMS收集器无法处理浮动垃圾,可能会出现“Concurrent Mode Failure”失败而导致另一次Full GC产生。(浮动垃圾:GC期间产生的垃圾,无法在当次收集中处理掉它们,只能留在下一次GC时再清理掉。)
  3. CMS会产生大量空间碎片

G1收集器(既用于年轻代,又用于老年代)(-XX:+UseG1GC,复制+标记-整理算法)

  • 并行和并发(使用多个CPU)
  • 分代收集
  • 空间整合(标记整理算法)
  • 可预测的停顿

特点:

将整个Java堆划分为多个大小相等的Region。

年轻代和老年代不再物理隔离。

5、GC相关的面试题

1)Object的finalize()方法的作用是否与C++的析构函数作用相同

  • 与C++的析构函数不同,析构函数调用确定,而它的是不确定的。
  • 将未被引用的对象放置于 F-Queue队列。
  • 方法执行随时可能会被终止。
  • 给予对象最后一次重生的机会。
  • obje的finalize()不会立即终止,还需要进行2次标记,c++中析构函数,会立即终止。

2)、Java中的强引用,软引用,弱引用,虚引用有什么用?

强引用:(Strong Reference)

  • 最普遍的引用:Object obj= new Object()。
  • 抛出 OutofMemoryError(内存溢出)终止程序也不会回收具有强引用的对象。
  • 通过将对象设置为nu来弱化引用,使其被回收。

软引用:(Soft Reference)

  • 对象处在有用但非必须的状态
  • 只有当内存空间不足时,GC会回收该引用的对象的内存
  • 可以用来实现高速缓存

String str = new String(“abc”);

SoftReference softReference = new SoftReference<>(str);

弱引用:(Weak Reference)

  • 非必须的对象,比软引用更弱一些。
  • GC时会被回。
  • 被回收的概率也不大,因为GC线程优先级比较低。
  • 适用于引用偶尔被使用且不影响垃圾收集的对象。

String str = new String(“abc”);

WeakReference weakReference = new WeakReference<>(str);

虚引用:(PhantomReference)

  • 不会决定对象的生命周期
  • 仼何时候都可能被垃圾收集器回收
  • 跟踪对象被垃圾收集器回收的活动,起哨兵作用
  • 必须和引用队列 Reference Queue联合使用

String str = new String(“abc”);

ReferenceQueue queue = new ReferenceQueue<>();

PhantomReference ref = new PhantomReference<>(str, queue);

四种引用的区别?

强引用>软引用>弱引用>虚引用

类层次结构

引用队列(Reference Queue)

  • 无实际存储结构,存储逻辑依赖于内部节点之间的关系来表达。
  • 存储关联的且被GC的软引用,弱引用以及虚引用。
目录
相关文章
|
8月前
|
算法 Java UED
JVM GC垃圾回收
JVM GC垃圾回收
113 3
JVM GC垃圾回收
|
4月前
|
算法 Java
JVM GC 垃圾回收
【1月更文挑战第3天】JVM GC 垃圾回收
|
8月前
|
缓存 算法 安全
JVM垃圾回收GC
这是JVM系列知识的最后一篇文章,本文围绕垃圾回收GC,涉及常用的垃圾回收算法,以及几种垃圾回收器。
68 0
|
12月前
|
Java 程序员
什么是GC
GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:
|
12月前
|
算法 Java 程序员
【GC 垃圾收集器】
【GC 垃圾收集器】
|
算法 Java 程序员
|
Java
GC是什么? 为什么要有GC?
GC是垃圾收集的意思(Gabage Collection)
122 0
|
存储 Java 程序员
GC的前世与今生(二)
GC的前世与今生(二)
150 0
GC的前世与今生(二)
|
开发框架 算法 Java
GC的前世与今生(一)
GC的前世与今生(一)
161 0
GC的前世与今生(一)
|
算法 Java 数据库连接
GC的前世与今生(三)
GC的前世与今生(三)
90 0