《深入理解Java虚拟机》总结——垃圾回收

2019-10-22  本文已影响0人  Fearimdly

最近看完了《深入理解Java虚拟机》的自动内存管理章节,觉得有必要稍微总结一下。实际上我觉得这本书里面有很多地方都只是讲了个大概,就比如这一章节中对7种垃圾回收器的介绍就仅仅是介绍而已,实现的细节都没有讲到。当然了,这本身也因为GC是一个复杂的体系,这么薄薄的一本书也不可能讲的完。

但是看书呢,总有个问题,就是看了就忘,所以为了防止自己忘记,就做了这么一个大纲,然后记上笔记,等到以后复习的时候,就按照这个大纲回忆。

点击获取xmind文件

《深入理解Java虚拟机》总结——垃圾回收.png

食用方法:

  1. 阅读《深入理解Java虚拟机》
  2. 过段时间开始回忆,点击这里查看答案


    截屏2019-10-22下午10.42.52.png截屏2019-10-22下午10.42.52.png

特别注意

  1. 《深入理解Java虚拟机》这本书的GC部分本身已经是总结了,所以这个算是总结的总结
  2. 没有《深入理解Java虚拟机》中的4种垃圾回收算法和7种垃圾收集器的总结,因为他们本身内容就很少,而且CMS和G1收集器讲的也不清楚
  3. 随后加了个dalvik和hotspot对比的总结,具体dalvik的实现推荐大家去看老罗的文章,art的还没来得及看

文字版

可能xmind这个软件需要钱,那就提供一个文字版吧

GC ROOTS有哪些

  1. 虚拟机栈中引用的对象
  2. 方法区的常量和静态变量引用的对象
  3. 本地方法引用的对象

四种引用及垃圾回收器对它们的回收策略

  1. 强引用。一般的引用都是强引用,垃圾回收器不会随意回收强引用
  2. 软引用。当内存不足时,垃圾回收器会把软引用放入可回收范围等待回收
  3. 弱引用。弱引用的对象只能活到下一次回收
  4. 虚引用。虚引用不能获取对象,仅仅可以再对象被回收时收到一个系统通知

对象不可达后,就真正死亡了吗?虚拟机是如何执行finalize方法的

对象被标记为不可达后,会被检查是否重写了finalize方法以及有没有执行过finalize方法。如果有重写并且没有执行过的话,虚拟机会把这些对象放到F-Queue中,让finalizer线程去执行这些对象的finalize方法,如果这些对象没有把自己“救活”,那么就会真正标记为“死亡,可以回收”

finalize方法可靠吗

finalize方法不可靠,优先级极低,finalizer线程的优先级也很低,虚拟机只保证会启动这个线程,但是不保证执行结果,建议程序员忘掉这个方法。

保守式GC

什么是不明确的根

我们以调用栈为例,调用栈中存在函数的局部变量和参数的值,这些可以是引用也可以是int之类的基本数据类型。在栈中这些值就是一串数字的排列,所以无法知道哪些是指针哪些不是指针

指针和非指针的识别

  1. 检查是不是正确对齐的值,在32位机器中,值应该是4的倍数,在64位中,值应该是8的倍数
  2. 是不是指向堆内
  3. 是不是指向对象的开头

举例说明貌似指针的非指针

例如有连个地址块上的值都是0x00d0caf0,但是无法分辨到底是这到底是指针还是数值

貌似指针的非指针的对象会被保留

理解“不明确的数据结构”

有的时候,堆里的对象中的数据也会存在无法分清是指针还是非指针的情况

相对应的,就有“半保守式GC”,即在对象上带有类信息,来确保数据结构的明确

优点

缺点

准确式GC

HotSpot的算法实现

简述Hotspot的分代GC策略

Hotspot将Java堆分成新生代和老年代,之前还有永久代。新生代中分为eden区和survivor区,survivor区有两种,分别是From区和To区,默认情况下,他们的大小比例为8:1:1。一般来说,新分配的对象放入eden区,特别大的对象直接放入老年代。GC开始时,eden区中存活的对象复制到To区,From区中的对象如果年龄达到阙值就复制到老年代,否则复制到To区,然后清空eden和From,同时将From和To调换,经过一轮GC还存活的对象,将其年龄+1。如果To区不够存放来自eden和From的存活对象时,需要老年代做分配担保,存在老年代中

Hotspot如何动态判定对象年龄

如果一个survivor区中某个年龄对象的总和大于survivor区的一半,那么年龄大于等于这个年龄的直接进入老年代

理解“空间分配担保”

dalvik和Hotspot在GC方面有哪些不同

  1. 首先相对于Hotspot中CMS系的垃圾回收器,dalvik没有采用分代回收算法,而是采用了标记清除法
  2. dalvik的GC是半保守式GC,而Hotspot中各个垃圾回收器都是准确式GC。
  3. dalvik在标记阶段使用的是位图标记法,原因是Zygote Heap写时复制技术
  4. 位图标记法采用的是两个位图,一个用来记录上一次GC之后还存活的对象,一个用来记录本次GC还存活的对象,然后对他们做异或运算,得到本次GC需要回收的对象
上一篇 下一篇

猜你喜欢

热点阅读