Java基础七:关于虚拟机的基本知识(二)

怎样确定一个对象为垃圾?

  • 判断一个对象是否是垃圾,分为两种方法:引用计数法和可达性分析算法
    • 引用计数法:当有一个地方引用它,则计数器加一;引用失效就减一,当计数器为0时,表示不会被使用,那么就是垃圾。这个算法性能其实很高,但是它有一个致命的缺点就是Java里有相互引用,那么这总算法就没法正确判断是否是垃圾。
    • 可达性分析算法:以GC Roots的根对象作为起始节点,根据引用关系向下搜索,搜索所走过的路称为引用链,如果对象和GC Roots之间没有引用链,表明该对象不可能再被使用,属于垃圾,等待被回收。
      可达性分析算法是主流的垃圾判断方法,可以作为GC Roots的对象有:虚拟机栈中引用的对象、方法区中静态属性引用的对象、方法区中常量引用的对象、本地方法区中引用的对象、被同步锁持有的对象等

常用的垃圾回收算法有哪些?并且有什么优缺点

  • 常用的垃圾回收算法有:复制算法、标记清除算法、标记整理算法
    • 复制算法:将可用对象分为大小相等的两块,每次只使用其中一块,当内存用完了,就把还活着的对象复制到另一块上面,然后把使用过的内存空间一次清理掉,该算法只需要移动堆顶指针按顺序分配即可,简单高效,但是缺点是可使用空间时内存的一半(新生代采用复制算法,分为Eden区(占80%),s0和s1(各占10%))
    • 标记清除算法:首先标记出需要回收的对象,标记完成后,统一回收掉所有被标记的对象,简单方便,但是执行效率不稳定,因为如果是大对象需要回收,那么就需要很长时间标记,另外会产生空间碎片,浪费内存资源
    • 标记整理算法:标记整理算法相当于是对标记清除算法的一种改进,标记要回收的对象,然后没有直接清理对象,而是把所有存活的对象都移动到内存空间一端,然后直接清理掉边界以外的空间,没有内存空间的浪费,其实执行效率也是不稳定的
      没有最好的算法,只有根据不同场景找到最合适的算法。

简述你对吞吐量和停顿时间的理解

  • jvm中 ,执行用户的代码占的时间/(执行用户的代码占的时间+GC时间) ,假如执行用户的代码占的时间是99 分钟,GC时间一分钟,则吞吐量为99% ,吞吐量越大。系统越好,如何设计系统,导致系统吞吐量高,因为我们知道,垃圾回收,多种垃圾收集器,也不能保证系统不会停顿,因为系统在垃圾回收强制挂起所有的用户线程在用户不可见的情况。所以这个停顿时间是我们设计选用垃圾回收器的考虑。
  • 停顿时间并不是越短越好,因为停顿时间越短,相对的,垃圾回收时回收的垃圾就相对越少,所以,具体的时间还是需要根据我们具体的业务而定,不能一味的为了吞吐量而调小停顿时间。

常用的垃圾收集器,以及他们适用的区域和特点

  • 1.Serial收集器:最基础、历史最悠久的收集器,属于单线程工作的收集器,当它进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束,称之为“Stop The World”,在用户不可知不可控的情况下把用户正常工作的线程全部暂停,所以说对很多应用无法接受。但是,迄今为止,它依然是HotSpot虚拟机运行在客户端模式下的默认新生代收集器,因为它简单高效,它是所有收集器里额外内存消耗最小的。对于客户端模式下,收集几十兆或者一两百兆的新生代,还是比较适用的。
  • 2.ParNew收集器:其实是Serial收集器的多线程版本。虽然它没有别的亮点,但是在JDK7之前,HotSpot虚拟机的service模式中却是经常使用的,因为只有它可以和CMS收集器配合使用,现在有了比如C1收集器,ParNew已经退出历史舞台了。
  • 3.Parallel Scavenge收集器:也是一款新生代收集器,同样是基于标记–复制算法实现的,也是能够并行收集的,它所关注的重点是达到一个可控的吞吐量,它提供了两个参数用于精确控制吞吐量:最大垃圾收集停顿时间:-XX:MaxGCPauseMillis,另一个就是直接设置吞吐量大小:-XX:GCTimeRatio。另外,还有一个参数:-XX:+UseAdaptiveSizePolicy,这是一个开关参数,激活之后,就不需要指定新生代的大小、Eden和Survivor的比例、晋升老年代对象大小等参数,虚拟机会根据当前系统的运行情况动态调整这些参数以提供合适的停顿时间和最大的吞吐量,这种调节方式称为垃圾收集的自适应的调节策略。
  • 4.Serial Old收集器:是Serial收集器的老年代版本,同样是一个单线程收集器,使用标记整理算法,主要提供给客户端模式下的HotSpot虚拟机使用。如果在服务端模式下,JDK5之前会使用,另一个就是作为CMS收集器发生失败时的后背预案。
  • 5.Parallel Old收集器:Parallel Scavenge收集器的老年代版本,支持多线程并发收集,基于标记整理算法,从JDK6开始使用,与Parallel Scavenge搭配使用,效果比较理想
  • 6.CMS收集器:属于一种以获取最短停顿时间为目标的收集器,目前多数java应用都是B/S架构,给用户带来最好的体验,那么就可以考虑这款收集器,基于标记清除算法,,它的运作包括四个步骤:1)初始标记,2)并发标记,3)重新标记,4)并发清除。由于整个过程中耗时最长的并发标记和并发清除阶段,垃圾回收器线程可以和用户线程一块工作,所以说,总体上看,CMS收集器的回收过程可以与用户线程一起并发执行,主要优点:并发收集,低停顿,考虑到标记清除存在内存碎片的缺点,CMS提供了内存碎片整理的机制作为弥补。
  • 7.Garbage First收集器(G1):它开创了收集器向局部收集的设计思路和基于Region的内存布局形式。G1主要是面向服务端应用的垃圾收集器。G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆分为大小相等的独立区域(Region),每一个Region都可以根据需要扮演新生代的Eden空间、Survivor空间或者老年代空间,收集器可以针对不同的Region采用不同的策略去收集。Region中还包括一个Humongous区域,专门用来存储大对象,G1认为只要是超过了Region一半的对象即可称为大对象。G1收集器的运作过程大致可分为四步:1)初始标记,2)并发标记,3)最终标记,4)筛选回收,除了并发标记外,也是需要暂停用户线程的
  • 8.ZGC收集器:属于低延迟垃圾收集器,它希望在尽可能对吞吐量影响不大的前提下,实现任意堆内存大小下都可以把垃圾收集的停顿时间限制在10毫秒以内的低延迟。它也采用基于Region的堆内存布局,ZGC的Region具有动态性----动态创建和销毁,以及动态的区域容量大小。它标志性的设计是染色指针技术。
    HotSpot虚拟机提供了种类繁多的垃圾收集器,选择太多反而令人踌躇难决,若只挑最先进的显然不可能满足所有应用场景,针对不用的业务,应该选择最合适的垃圾收集器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值