垃圾回收简介
GC root
GC 根是可以从堆外被访问的对象,主要包含线程栈和系统类,这些对象总是可以触达。
GC 算法会任意一个根对象开始,扫描所有可达对象,不可达对象则是无效对象。
当GC算法找到不适用对象,JVM会回收这些对象占用的内存,并将这些内存分配给其他对象
————对内存进行压缩以避免内存碎片
所有线程都停止运行的停顿方法叫作——STW(STOP-THE-WORLD PAUSE)
优化的主要点也是减少这些停顿造成的性能开销
分代垃圾回收器
垃圾回收的工作方式是将堆分成两代
分代设计的原因是因为大多数操作会产生大量的临时对象
young generation(Eden,Survivor)
新生代是整个堆的一部分,对象首先在新生代分配,当新生代填满,GC会停止应用程序线程,清空新生代。
不在使用的对象丢弃,有使用的则移动到新的位置。整个操作时Minor GC OR Young GC
pros and cons
@Full GC 应用程序线程较长时间的停顿
@新生代是堆的一部分。处理体积小。
@STW频繁,但是停顿的时间短
@新生代的对象分配方式
Eden和Survivor1 2方式
收集之后Eden Survivor 1 被清空压缩
@随着对象逐渐的移动到老年代
generation 老年代
使用并发回收器应用程序听停顿更少,但是会使用更多的CPU
对于批处理应用程序GC的权衡
如果CPU足够使用,使用并发回收避免Full GC停顿让任务执行更快
如果CPU有限,则会降低任务的执行性能花费更多时间
GC 算法
Serial
-XX:+UseSerialGC 如果禁用则需要使用其他GC处理
使用单线程处理堆,在处理堆的时候会停止所有线程(Minor or Full GC),在Full GC 会完全压缩老年代
Through put
-XX:+UseParallelGC
使用多线程收集新生代和老年代,并行回收器
G1 GC
-XX:+UseG1GC
官方整体建议是处于中等的停顿时间————可供参考
使用并发回收策略以最小停顿回收堆。
G1 GC将堆划分为多个Region(512),但仍然认为堆有两代
一些区域组成了新生代,回收新生代G1还是会暂停所有应用程序线程。并将所有活跃的线程移动到老年代或者Survivor(此时使用多线程操作)
G1 GC处理老年代是后台线程处理,大多数工作不需要停止应用线程。
老年代被划分为多个区域,G1 GC可以通过将对象从一个区域复制到另一个区域来清理老年代的对象
意味着在正常处理堆过程的时候对堆进行了压缩
尽管这会有可能碎片化,G1 会尽量避免
避免使用Full GC的代价是消耗CPU周期,在应用程序运行的同时,G1用来处理老年代的线程必须有可用CPU周期
CMS垃圾回收器
-XX:+UseConcMarkSweepGC
并发回收器,多线程收集MinorGC过程停止所有应用线程
后台处理堆的过程中不能压缩堆的缺陷和G1的出现而在JDK11被淘汰
实验性收集器
触发和禁用显示的垃圾回收
通常jvm判定有必要进行GC,gc会触发
新生代满了会触发MinorGC
老年代满FullGC 触发
当堆要满的时候并发收集器
1.应用程序的一种强制GC的入口是System.gc()这个操作总是会触发FULL gc 会造成应用程序停顿
2.命令行收集 jcmd PID GC.run 描述:对 JVM 执行 java.lang.System.gc()
3.通过系统属性定时进行收集
Dsun.rmi.dgc.server.gcinterval=N
Dsun.rmt.dgc.client.gcinterval=N 毫秒单位
可以通过JVM参数加上-XX:DisableExplicitGC阻止三方代码中执行System.gc()