GC垃圾回收

GC垃圾回收,第1张

GC垃圾回收

目录

JVM内存分代模型(用于分代垃圾回收算法

常见的垃圾回收算法

stop the world

GC为什么会有全局停顿:

什么时候回触发GC:

GC的类型


JVM内存分代模型(用于分代垃圾回收算法)

  1. 年轻代(Young Gen):年轻代主要存放新创建的对象,内存大小相对会比较小,垃圾回收会比较频繁。年轻代分成1个Eden Space(伊甸区)和2个Survivor Space(幸存者区),Survivor Space中又分成from和to。当对象在堆创建时,将进入年轻代的Eden Space。垃圾回收器进行垃圾回收时,扫描Eden Space和from,这些对象经过第一次Minor GC后,如果仍然存活,将会被移到to。对象每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中。因为年轻代中的对象都是朝生夕死的(80%以上),所以在年轻代使用的垃圾回收算法是赋值算法,复制算法不会产生内存碎片。扫描完毕后,JVM将Eden Space和from清空,然后交换from和to的角色。
  2. 年老代(Tenured Gen):年老代主要存放JVM认为生命周期比较长的对象,内存大小相对会比较大,垃圾回收也相对没有那么频繁,年老代主要采用压缩的方式来避免内存碎片(将存活对象移动到内存片的另一边,也就是内存整理)。当然,有些垃圾回收器(譬如CMS垃圾回收器)处于效率的原因,可能不会进行压缩。
  3. 持久代(Perm Gen):持久代主要存放类定义、字节码和常量等很少会变更的信息。
常见的垃圾回收算法

标记清除算法:标记清楚算法是现代垃圾回收算法的思想基础。标记清除将垃圾回收分为两个阶段:标记阶段和清除阶段。

  • 标记阶段:首先通过根节点,标记所有从根节点开始的可达对象。因此未被标记的对象就是未被引用的垃圾对象。
  • 清除阶段:在清除阶段,清除所有未被标记的对象。

标记清除算法的缺点:

  • 等待时间长,导致stop the world的时间很长。
  • 不能解决内存碎片的问题。

复制算法:

将原有的内存空间分为两块,每次只使用其中的一块。在垃圾回收的时候,将存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象。交换两个内存的角色,完成垃圾回收。

复制算法的缺点:

  • 空间浪费,复制算法每次都只对半区内存进行回收,,复制算法要想使用,最起码对象的存活率要非常低才行,而且重要的是要克服50%的内存浪费。
  • 如果要应对所有对象都100%存活的极端情况,就必须要有很大的额外空间担保,所以这种算法不适用很多的对象存活率都很高的时候(年老代)。

标记整理算法:

在标记清除算法的基础上做了一些优化,和标记清除算法一样,首先需要从根节点开始,对所有可达对象做一次标记。但是之后,将所有存活的对象压缩到内存一端,然后清理边界外所有的空间。

标记整理算法的缺点:

  • 效率很低,不仅要标记所有存活的对象,还要整理所有存活对象的引用地址。

总结:

  • 效率:复制算法>标记整理算法>标记清除算法
  • 内存整齐度:复制算法>标记整理算法>标记清除算法
  • 内存利用率:标记整理算法>标记清除算法>复制算法
stop the world

java中一种全局暂停的现象,全局停顿,所有代码停止,native代码可以执行,但不能和JVM交互。多半情况下是由于GC引起的。

 

危害:

  • 长时间服务停止,没有响应(将用户正常工作的线程全部暂停掉)
  • 比如上面的这主机和备机:现在是主机在工作,此时如果主机正在GC造成长时间停顿,那么备机就会监测到主机没有工作,于是备机开始工作了;但是主机不工作只是暂时的,当GC结束之后,主机又开始工作了,那么这样的话,主机和备机就同时工作了。主机和备机同时工作其实是非常危险的,很有可能会导致应用程序不一致、不能提供正常的服务等,进而影响生产环境。
GC为什么会有全局停顿:
  • 避免无法彻底清理干净
  • GC的工作必须在一个能确保一致性的快照中进行
什么时候回触发GC:
  • 当新对象生成,并且在Eden申请空间失败时,就会触发Minor GC
  • 年老代(Tenured)被写满
  • 持久代(Perm)被写满
  • System.gc()被显示调用
  • 上一次GC之后Heap的各域分配策略动态变化
GC的类型

一、年轻代垃圾回收器:

1、Serial:

单线程GC,在进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。

2、ParNew:

就是Serial的多线程版本,除了使用多条线程进行垃圾收集之外,其余都和Serial完全一样。老年代使用CMS时,新生代会默认使用ParNew,也只有ParNew可以和CMS配合使用。

3、Paraller Scavenge:

并行多线程收集器,server模式下默认GC的方式。停顿时间短,良好的响应速度可以提升用户体验。有自适应调节策略。


二、老年代垃圾回收器:

1、Serial Old:

是Servial的老年代版本,同样是一个单线程收集器,每次进行回收都很耗时。

2、Parallel Old:

Parallel Scavenge收集器的老年代版本,多线程

3、CMS:

一种获得最短停顿时间为目标的GC,目前用重视响应速度的服务端上(如BS架构)。使用XX:+UseConcMarkSweepGC指定使用。

优点:响应时间短

缺点:对CPU资源很敏感,会导致应用变慢,总吞吐量会降低

4、G1:

并行与并发:充分利用多CPU的优势,使用多个CPU来缩短Stop-The-World停顿的时间。通过并发的形式让java程序据继续执行。

分代收集:既可以收集新生代也可以收集老年代

空间整合:采用标记-整理算法

可预测停顿:可以建立可预测的停顿时间模型,从而达到降低停顿时间的要求。
 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5682752.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存