JVM之常见GC算法(二)

释放双眼,带上耳机,听听看~!

GC主要的工作区域主要在堆内存中,主要对堆内存进行垃圾回收。
GC工作的第一步就是先在堆内存中找到可回收的垃圾(堆内存中不被使用的对象)

常见的GC方式

常见的GC方式有以下两种,分别应用于不同的场景

1)引用计数法
常应用于:(微软的COM/ActionScrip3/Python等场景)

缺点:

  • 每次对对象赋值时均要维护引用计数器,且计数器本身也有一定消耗;
  • 比较难处理循环引用
  • JVM的实现一般不采用这种方式

2)跟踪(Tracing)
跟踪(Tracing)方式采用了如下几种GC算法,

  • 复制(Copying)
  • 标记-清除(Mark-Sweep)
  • 标记-压缩(Mark-Compact)
  • 标记-清除-压缩(Mark-Sweep-Compact)

以上列出了几种算法的名称,下面讲解这几种算法的工作原理

复制算法(Copying)

复制算法原理
1)此算法把内存分为两块,分别为From块和To块。然后从根集合(GC ROOT)开始。
2)从From中找到可用的存活对象,拷贝到To中;然后From、To交换身份,交换身份后From为To,To为From。
3)下次内存分配从正真的To(但是交换身份后还是为From)开始;因为从From中拿取到零散的对象后有序的放到To中,所以可以实现没有内存碎片。
4)这种算法不涉及到对象的删除,只是把可用的对象从一个地方拷贝到另一个地方,因此适合大量回收的场景,比如新生代回收。
5)这种方式会不断的创建对象、复制对象、清空不可用对象、交换空间,因为会不断的交换空间,所以To空间一直是空的,From才是使用的空间。

标记-清除算法(Mark-Sweep)

标记-清除算法原理
标记-清除算法不会对内存进行分块。则是先对内存中的所有对象进行扫描,然后标记,最后清除。
1)标记:此算法会先对内存空间进行扫描,然后对存活的对象进行标记。

2)清除:标记过后,然后此算法会再次进行扫描整个内存空间,回收未被标记的对象(未被标记的对象则为垃圾对象),使用free-list可以记录区域。

此算法不像Copying算法一样将内存分为两个空间,但是它需要扫描两次内存,需要两步来实现,而且会产生内存碎片。

标记-压缩算法(Mark-Compact)

标记-压缩算法原理
1)标记:先对内存空间进行扫描,然后对存活的对象进行标记。(与标记清除的标记步骤一致)

2)压缩:再次对内存空间进行扫描,然后将标记对象(可用对象)向内存的一端移动(进行可用对象整理),然后将会出现一端内存空间连续使用,一端内存空间为空闲内存。

这种方式可以有效的整理内存,不产生内存碎片,但是有移动对象的成本。如果将内存中的第八块对象移动到第三块对象还要考虑这两块内存空间大小是否一样,如果不一致,那么还有更加复杂的机制。

标记-清除-压缩算法(Mark-Sweep-Compact)

标记-清除-压缩算法原理
此算法为 标记-清除和标记压缩算法的整合
1)同样是先扫描所有内存中的对象,然后对可用对象进行标记。

2)再次扫描内存中的所有对象,对没有标记的对象进行删除操作(这个时候存在内存碎片)。

3)然后再次扫描内存中的所有对象(已经经过清除不可用对象步骤向一端进行滑动,解决内存碎片问题以及减少了移动对象的成本


本章完 下章讲解HotSpot内存管理

人已赞赏
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索