JVM垃圾回收算法你都知道吗?
Python实战社群
Java实战社群
长按识别下方二维码,按需求添加
扫码关注添加客服
进Python社群▲
扫码关注添加客服
进Java社群▲
作者丨java金融
来源丨java金融
怎么判断对象"已死"?
1.引用计数法
不能解决对象循环依赖的问题。因此一般不用这种。
2.可达性分析算法。
GCRoots 不可达时 对象死,采用这个。
垃圾收集算法
1.标记清除算法
1.标记、清除阶段效率不高。
2.标记清除之后会产生大量不连续的碎片,导致分配较大的对象时候,无法找到足够的连续内存。
2.复制算法
1.两块相同的内存空间,一块使用,一块空闲,导致空间浪费。不存在碎片问题。
3.记整理算法
1.标记过程与"标记清除算法"一样,整理过程是让所有存活对象都往一端移动,然后直接清理掉边界以外的内存。
4.分代收集算法。
把对象进行分代,新生代和来年代。
总结
新生代一般用复制算法,老年代一般用标记整理或者标记清除算法。
垃圾收集器
Serial收集器
作用于新生代
单线程收集
采用复制算法
开启方式:-XX:+UseSerialGC
Client模式下的默认新生代收集器。进行垃圾收集时,必须Stop the world,直到它收集结束
ParNew收集器
作用于新生代。
多线程收集
采用复制算法
-XX:+UseParNewGC-XX:ParallelGCThreans=2(2指定垃圾收集的线程数)
Server模式下的默认新生代收集器
ParallelScavenge收集器
新生代
多线程
复制算法
-XX:MaxGCPauseMillis控制最大垃圾收集时间 -XX:GCTimeRatio 控制吞吐量大小
吞吐量优先收集器目标:控制吞吐量吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)吞吐量越高说明CPU时间利用率越高。
SerialOld收集器
老年代
单线程
标记整理算法
这个收集器的主要意义也是在于给Client模式下的虚拟机使用。如果在Server模式下,主要两大用途:1.在JDK1.5以及之前的版本中与ParallelScavenge收集器搭配使用。2.作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用
ParallelOld收集器
老年代
多线程
标记整理
ParallelOld是ParallelScavenge收集器的老年代版本。这个收集器在1.6中才开始提供。在JDK1.5以及之前的版本中,Parallel Scavenge+Serial Old(单线程),无法充分利用多CPU的处理能力。1.6之后,终于有了名副其实的"吞吐量优先"收集器组合:Parallel Scavenge + Parallel Old。
CMS
老年代
多线程
标记清除算法
-XX:+UseConcMarkSweepGC新生代使用了PartNew
CMS在老年代的整个过程分为4个步骤:
1.初始标记stop the word 仅仅标记GC Roots能直接关联到的对象,速度很快
2.并发标记进行GCRoots Tracing的过程(判断对象是否仍在使用中)和用户线程一起工作。3.重新标记stop the word 修正并发标记阶段因用户程序继续运行而导致标记发生变动的那一部分标记记录。此阶段比初始标记阶段稍长,但远比并发标记阶段的时间短。
4.并发清除 和用户线程一起工作。
G1 收集器
内存组成:Eden、 Survivor、 Old、 Humongous
内存变化:字符串内部池,已经在JDK7中从永久代中移除,JDK1.7中,存储在永久代的部分数据就已经转移到了JavaHeap或者是NativeHeap。但永久代仍存在于JDK1.7中,并没完全移除,譬如符号引用(Symbols)转移到了native heap;字面量(internedstrings)转移到了javaheap;类的静态变量(classstatics)转移到了java heap持久代也移动到了普通的堆内存空间中,改为元空间 。
大对象的分配
1 TLAB(Thread Local Allocation Buffer)线程本地分配缓冲区
2 Eden区中分配
3 Humongous区分配
GC模式
G1提供了两种Young GC和Mixed GC,两种都是Stop The World(STW)
近期精彩内容推荐: