欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JVM培训之一些GC算法的理论知识

程序员文章站 2022-05-29 13:17:53
很精彩的一次内部分享,介绍了大部分的GC算法理论知识,JVM博大精深,本篇文章只是结合本次内部分享总结的一些理论知识,如果有大佬有疑问,欢迎留言指出! Concurrent:并发,程序一边运行一边做GC Parallel:并行,一块区域,一个人做清扫,需要100s,但是把区域分成两块,用两个人扫,时 ......

很精彩的一次内部分享,介绍了大部分的gc算法理论知识,jvm博大精深,本篇文章只是结合本次内部分享总结的一些理论知识,如果有大佬有疑问,欢迎留言指出!

concurrent:并发,程序一边运行一边做gc

parallel:并行,一块区域,一个人做清扫,需要100s,但是把区域分成两块,用两个人扫,时间就缩短了一半;所以gc算法有并行的,有不是并行的,这些都是可以根据自己的实际业务去选择的,只有最适合自己的gc算法;

stop the world:简称stw,某些gc算法当中,当需要做gc的时候,程序是必须停下来的,程序就是一个终止状态,当gc结束之后再恢复;java的gc很多时候都是stw,举一个简单的栗子,一边扫地一边嗑瓜子,这样的话是永远扫不干净的,内存的使用率就不是很高,当然stw有一个很大的缺点,就是程序必须终止,如果说做一次gc用时太长,需要十几秒或者一分钟或更多,那肯定是无法忍受的,这就需要gc调优来完成,通过算法把时间控制在最短,让用户无感知;

root set:公集合,gc的时候会确定现在哪些对象还是存活的,

generation gc:分代gc,先说一代gc,比方说现在有一个2g的内存区域,那么需要gc的时候,需要把整块内存区域2g遍历一次,来做gc,这是一个很复杂的过程,需要判断这么多的对象是否引用或者被引用,可想而知耗时肯定会很长;以老王的经验,1g内存做一次full gc停顿时间在1-3s,100g内存做一次full gc,停顿时间在1-3min,也就是说这几分钟程序什么都干不了,肯定是无法接受的;所以产出了分代gc,把一个区域分成几个部分,年轻代1,年轻代2,和年老代。比方说程序开始运行,新产生的对象放在年轻代1,装满之后,结合copy算法,从root节点出发,可能真正存活的对象只有很少一部分,那么我们只把这部分对象拷贝到年轻代2里面,然后将年轻代1区域全部清扫掉,这个copy算法非常高效,但前提是需要程序的对象大部分都是用完一次就可以扔掉的,不然的话,存活的对象太多了,copy算法就变得很低效了;所以copy算法的效率取决于剩余的对象,剩余的对象越多,效率越低,剩余的对象越少,效率越高;

refcount:引用计数算法,当有指针指向这个对象的时候,就把计数器+1,当不指向这个对象的时候把计数器-1,当这个对象的计数器为0的时候,这个对象的内存就可以释放掉了,python就是用的这个算法,官方的python流派就是用的这个算法,微软的com组建结构也是用的这个引用计数算法;这个算法两个缺点:效率低,因为访问对象是一个很频繁的操作,这样频繁做++;扫不干净,循环列表,a->b->c,其实外部没有引用,但是内部有互相引用,其实abc都是垃圾;

marksweep:标记清除算法,有很多对象,从公集合出发找其他的对象,是活的对象就做标记,标记的过程中,程序是不能跑的,当标记完了之后,没有被标记的对象,就都可以释放掉了,但是清扫之后的内存区域会变得千疮百孔,再分配内存的时候,需要在这些内存中,找一个合适自己的内存区域;

markcompact:标记压缩算法,可以理解是标记清除算法的一个升级版,同样是在活对象上标记,但是它会选一个活对象作为一个端,把另外标记的活对象往这一端挤,这样被释放的区域就会是一大块的;

safepoint:当代码运行到某个点,这个点可以做gc,这个点就叫safepoint,做gc的时候,所有的线程都需要停下来,就是所有的线程需要跑到这个安全点,跑到这个点的时候,java虚拟机会生成一条指令,这个指令会让这个线程访问一个内存地址,这也是为了快速响应;因为线程停下来做别的事情非常耗性能;

reference:强引用,强引用是我只要引用你,你就不会被垃圾回收;当然还有weakreference弱引用和软引用softreference等;

java虚拟机的几个gc算法:

  年轻代:serial:串行,stw特性

      parnew:多线程,也是stw

      parscavenge:多线程,同样是stw,是parnew升级版

 

  年老代:cms:试图平衡停顿时间,这个算法的过程为:initialmark->ccmark->remark->ccsweep

      serialold:markcompact算法上面提到过的

      parold:同样是markcompact算法,是serialold升级版

年轻代和年老代gc算法是可以组合的,除了部分;

zgc:java11版本发布推出,管理tb级内存,gc时间控制在10ms;