0
点赞
收藏
分享

微信扫一扫

GC

雪域迷影 2022-02-23 阅读 72



文章目录


  • ​​垃圾标记算法​​

  • ​​解决​​
  • ​​对象被判定为垃圾的标准​​
  • ​​判定对象是否为垃圾的算法​​

  • ​​引用计数算法​​

  • ​​优缺点​​
  • ​​缺点代码演示​​

  • ​​可达性分析算法​​
  • ​​可以作为GC ROOT的对象​​


  • ​​垃圾回收算法​​

  • ​​标记-清除算法​​
  • ​​碎片化​​
  • ​​复杂算法​​
  • ​​标记整理算法​​
  • ​​分带收集算法 主流​​

  • ​​Minor GC年轻代垃圾复制算法​​
  • ​​如何晋升至老年代​​
  • ​​Full GC老年代​​

  • ​​jdk7及以前 对比 jdk8​​
  • ​​参数调优​​

  • ​​新生代垃圾收集器​​

  • ​​其他线程等待gc线程​​
  • ​​安全点​​
  • ​​JVM运行模式​​
  • ​​Serial收集器​​
  • ​​老年代收集器​​
  • ​​及适用于年轻代又适老年代​​
  • ​​垃圾收集器之间的联系​​

  • ​​面试题​​

  • ​​Object的finalize()方法的作用是否与C++的析构函数作用相同​​
  • ​​Java的强引用、软引用、弱引用、虚引用,有什么用?​​
  • ​​综上比较​​
  • ​​类层次结构​​
  • ​​引用队列​​
  • ​​追源码​​
  • ​​引用对象放在ReferenceQueue代码示例​​



垃圾标记算法

解决


对象内存分配问题、回收分配给对象内存的问题


对象被判定为垃圾的标准


没有被其他对象引用


判定对象是否为垃圾的算法

引用计数算法

GC_垃圾回收

优缺点

GC_java_02

缺点代码演示

对象实例相互引用,循环引用

主流的gc没用这种方法

GC_垃圾回收_03

GC_垃圾回收_04

可达性分析算法


离散数学的图论理解
从gc Root 向下搜索走过的路径,成为引用链。
存活标记为可达。
垃圾对象则不可达


GC_java_05

可以作为GC ROOT的对象

GC_垃圾回收_06

垃圾回收算法

标记-清除算法

GC_垃圾回收_07

碎片化


不利于后来程序运行时,无法找到较大的连续内存分配


GC_java_08

复杂算法


对象存活率低的场景
不会有碎片,每次对每个半区进行回收



商用虚拟机,多采用这种方法回收年轻代基本只有10%存活
年轻代


GC_java_09

GC_老年代_10

标记整理算法


在标记清除做了改进
解决空间碎片化问题


GC_java_11

GC_垃圾回收_12

分带收集算法 主流


生命周期划分不同区域。采用不同垃圾回收算法


GC_java_13

Minor GC年轻代垃圾复制算法


所有java出生的地方。申请的内存和存放都是在此处
Java对象一般不需要长久存活,朝生夕灭


GC_垃圾回收_14

GC_老年代_15

GC_老年代_16

GC_java_17


每次gc年龄递增+1
通过调节年龄到老年代的参数,默认15岁


GC_垃圾回收_18

如何晋升至老年代

GC_垃圾回收_19

Full GC老年代


一般老年代回收,会伴随年轻代。
Full 比 Minor 执行慢10倍左右,但执行频率低



触发回收Full
老年代空间不足。
jdk1.7及以前永久代空间不足
CMS GC 同时。年轻代放不下,老年代也放不下。
GC_java_20


jdk7及以前 对比 jdk8


jdk8将永久代删掉了
年轻代:存活率低,采用复制算法
老年代:存活率高,采用标记整理、清除


GC_垃圾回收_21

GC_java_22

参数调优


空间分配:老:新大概2:1


GC_java_23

新生代垃圾收集器

其他线程等待gc线程

GC_老年代_24

安全点

什么是安全点?


JVM的快照下分析,其他线程停止等待gc线程。
不能存在gc分析过程中对象引用状态还在不停变换,因此分析结果在某个点具有确定性,这个点叫做安全点。
程序必须到达安全点才会停顿下来。
安全点太多,GC 过于频繁,增大运行时负荷;安全点太少,GC 等待时间太长。


GC_老年代_25

JVM运行模式


Server
启动慢,重型,运行稳定后变快
Client
启动快,轻型,运行后,没server快


GC_老年代_26

Serial收集器


减少gc线程等待时间(系统停顿时间)适合交互
在程序启动时可以设置 指定 收集器
Java最基本历史最悠久的收集器
jdk1.3.1以前是Java虚拟机年轻代的唯一选择


GC_垃圾回收_27


Server模式下的年轻代首选
除了Serial 只有ParNew与CMS配合使用


GC_java_28


多线程
关注系统吞吐量,适合后台计算。
如果对收集器调优不熟悉,可以在启动时加上自适应 调节策略,把内存管理和调优任务交给虚拟机执行。


GC_垃圾回收_29

GC_老年代_30

老年代收集器

GC_老年代_31


jdk6之后提供
比较尴尬的是
在此之前,如果年轻代选择了Parallel Scavenge,老年代必须选择Serial Old收集器
。由于老年代服务端单线程性能上的拖累。使年轻代Parallel Scavenge未必能达到吞吐量最大化的效果。单线程的老年代无法充分利用年轻代多线程cpu的处理能力。
因此在老年代很大,硬件高级的环境中。甚至没有ParNew和CMS的组合给力。
直到Parallel Old出现,可以与Parallel Scavenge组合吞吐量优先收集器有了名副其实的组合。
适用:吞吐量、cpu敏感的场合


GC_老年代_32


CMS占据着垃圾回收老年代的半壁江山
垃圾回收线程几乎和用户线程同时工作
但是还不能做到完全不需要(系统停顿时间),只是尽可能的缩短了应用时间
适用场景:对停顿比较敏感,需要更大的内存和cpu ,更牛的硬件
JVM中有很多存活时间相对较长的对象,可以用CMS
只扫描根直接关联的节点
缺点:标记清除,碎片化严重


GC_垃圾回收_33

及适用于年轻代又适老年代


用于替换掉JDK5中的CMS收集器

GC_垃圾回收_34
GC_垃圾回收_35


垃圾收集器之间的联系


CMS 和 G1使用了新的独立框架,而其他的共用框架类似


GC_垃圾回收_36

面试题

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


C++析构函数,调用时机确定,对象离开作用域就会被清除掉
Java的finalize(),具有不确定性,当垃圾回收器宣告一个对象死亡时至少经过两次标记过程。
可达性分析之后发现,当没有和GC ROOT相链接的引用链,会被第一次标记。并且判断是否执行finalize方法,如果对象覆盖finalize()方法且未被引用, 这个对象就会被放置在F-Queue队列中,并在稍后由虚拟机自动建立的低优先级finalize线程去执行触发finalize()方法 。(由于优先级比较低,不承诺等待其运行结束,方法执行了随时可能被终止)给对象创造了最后一次重生的机会



不建议使用:由于运行的不确定性较大,无法保证各对象的调用顺序,同时运行代价相当高昂。


GC_垃圾回收_37

代码证明

GC_垃圾回收_38

GC_老年代_39

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



宁可终止也不回收


GC_java_40



内存不够用再回收
适用:内存缓存
包装使用:SoftReference< String>
配合引用队列使用:


GC_老年代_41



见到就回收
垃圾回收优先级低
适用:偶尔使用
WeakReference< String >


GC_垃圾回收_42


必须和队列联合使用。软引用、弱引用也可以用此种方式
哨兵作用:判断是虚引用是否加入队列中,知道gc是什么时候执行的


GC_垃圾回收_43

综上比较

GC_垃圾回收_44

类层次结构

GC_垃圾回收_45

引用队列


依赖节点之间类似链表
链表的容器,其自己仅存储当前的head节点。后面的节点由referent.next()链接
除强引用,其他引用在gc后,将引用对象放在ReferenceQueue
GC_java_46


GC_java_47

追源码

GC_java_48


referent新创建对象的引用
queue类似链表结构
next指向下一个引用


GC_java_49

引用对象放在ReferenceQueue代码示例


开始时queue为空
normal打印载入的名字
weak没有打印
gc垃圾回收
weak载入到了主方法内,此时name被垃圾回收所以输出为null



对ReferenceQueue进行监控,如果有对象被回收,那么响应的Reference对象就会被放到Queue里面,就可以拿Refernce做一些事情。
如果不带Queue,就要不断的轮询Reference,通过不断的判断里面的get方法是否返回null ,来判断是否被回收。
通过Get方法来判断返回对象是否为空并不适用虚引用,因为此get方法返回值一直为null,只能通过Queue来判断
GC_垃圾回收_50
GC_垃圾回收_51


弱引用哨兵功能

GC_java_52

主方法

GC_java_53

GC_java_54

GC_老年代_55

输出

GC_java_56



举报

相关推荐

0 条评论