• 黑马JVM总结(十六)


    (1)垃圾回收器

    垃圾回收器分为以下: 

    吞吐量:垃圾回收时间占程序回收时间的一个占比,占比越低,吞吐量越高 

    (2)垃圾回收器_串行

    使用上面的开启串行垃圾回收器的JVM参数,它分为两个部分Serial工作在新生代,采用复制算法,SerialOld工作在老年代,采用标记+整理算法

    新生代和老年代 的垃圾回收器是分别运行的,新生代空间不足采用Serial来完成垃圾回收 Minor GC,老年代空间不足采用SerialOld来完成垃圾回收 Full GC

    (3)垃圾回收器_吞吐量优先

    回收流程: 

    多核CPU有4个线程都在跑,当内存不足了,触发了垃圾回收,这些用户线程会跑到一个安全点停下来, 跟串行上面不一样的是垃圾回收器会开启多个线程进行垃圾回收,这个垃圾回收线程的个数跟cpu的个数是相关的

    开启吞吐量优先垃圾回收器虚拟机参数:ParalleGC:并行的

    默认上1.8里已经开启了

    UseParllelGC:代表新生代的垃圾回收,采用复制算法  UseParllelOldGC:老年代,采用的标记+整理算法

    这两个只要开启一个它会连带的把另外一个也开启

    通过这个参数可以控制线程数

    自适应的调整大小策略:新生代的大小

    第一个是调整吞吐量的一个目标 radio默认为99 一般设为19  100分钟发生5分钟垃圾回收时间

    1/1+ratio  0.01:垃圾回收的时间不能超过总时间的%1,比如说工作了100分钟,只能有1分钟用于垃圾回收,如果达不到这个目标,Paralle回收器会调整堆的大小,一般把这个堆增大,增大以后垃圾回收的次数就变得不频繁了这样就可以达到垃圾回收的总时间的下降,从而达到吞吐量提高

    第二个是调整最大暂停时间 默认200毫秒

    这两个可能是有冲突的,上面的那个参数提高了通过把堆变大了(每次回收的时间可能增长),下面的参数可能就达不到

    反之把暂停时间变的短,意味着把堆的空间变小,这样垃圾回收的时间变短,吞吐量就下来了

    (4)垃圾回收器_ 响应时间优先

    concurrent:基于并发的,用户线程跟垃圾回收线程并发执行 ,垃圾回收的同时用户线程也能同时工作,进一步减少了STW(Stop the World)的时间

    并行:是指多个垃圾回收线程并行运行,但是不允许用户线程运行了 

    并发垃圾回收器工作流程:多个cpu并发执行,老年代发生了内存不足,这些线程到达安全点,停下来再CMS回收器执行一个初始标记,此时会Stop the World(用户线程停下来了)初始标记很快的(只标记根对象)时间非常短,初始标记结束下来,用户线程恢复运行,此时垃圾回收线程还可以并发执行,把剩余的垃圾找出来,这个时候跟用户线程是并发执行的(在这个时候在标记的同时用户线程也在同时工作,可能改变一些对象的引用,对垃圾回收产生干扰,所以之后需要重新标记一次),并发标记以后,还要进行一个重新标记还会触发Stop the World,从新标记完用户线程又可以重新运行 ,这个时候回收线程在做一次并发的清理

    前面这个是工作在老年代,后面这个是工作在新生代的垃圾回收器

    前面这个有时候发生并发失败的问题,这个时候采用一种措施把并发的垃圾回收器,换成单线程的垃圾回收器SerialOld

    前一个:并行的垃圾回收线程数:一般等于CPU的数目  后一个并发的GC线程数 :它一般设为并行线程数的四分之一 

    4个cpu  1个cpu用于垃圾回收,其他3个cpu留给用户线程工作

    红色垃圾回收  蓝色用户线程

    cms垃圾回收器,它对cpu占用不是特变高

    原来是4核都是为用户服务的,现在分出1核做垃圾回收,可用于计算的cpu个数变少,同样的工作量会变长,影响用户的吞吐量

    当并发执行的时候,用户线程可能产生新的垃圾,但是并发清理不能把新垃圾清理掉 ,新垃圾称为浮动垃圾,需要等下一次清理才能清理掉这样带来一个问题:因为在垃圾回收过程中产生新的垃圾,那么不能像原来其他垃圾回收器那样等到堆内存不足啦我才做垃圾回收,那么这些心垃圾就没处放了,需要预留一些空间保留浮动垃圾

    通过下面的参数进行控制:cms回收的内存占比 设为80%  就是内存不要等到内存不足时,只要老年代内存达到80%的时候,我就执行一个垃圾回收,就是为了预留一些空间给哪些浮动垃圾

    这个值设置越小,CMS执行垃圾回收的时机就早一些

    在重新标记中:有可能新生代的对象引用老年代的对象,重新标记必须扫描整个堆,通过新生代引用扫描老年代的对象,做那个可达性分析,这样对性能影响比较大,因为新生代创建的对象比较多,很多是要作为垃圾的 ,从新生代找老年代,就算找到了将来新生代的垃圾也要回收掉,相当于在回收之前做了无用的工作,怎么避免 这种现象嗯通过下面的参数:

    在重新标记之前,对新生代做一个垃圾回收,回收之后呢对象就少了将来扫描的对象就少,就会减轻重新扫描时的压力

    CMS垃圾回收器有一个特点它是基于标记+清除算法,当内存碎片非常多的时候,这样呢会造成将来分配对象时Minor GC不足,老年代由于碎片过多 也不足,会造成并发失败,UseConcMarkSweepGC就会退化为SerialOld,做一次单线程串行的垃圾回收,做一个整理,整理完呢,碎片减少了,我才能继续恢复工作,导致时间一下子变得很长,这是CMS垃圾回收器的一个问题

     

  • 相关阅读:
    冬天这么冷,到底要不要坚持送孩子入托?
    大数据开发集群搭建
    Go中的编程模式:Pipeline
    JDK1.8之前与之后 HashMap底层实现原理的差别
    P1059 [NOIP2006 普及组] 明明的随机数
    一些并查集的题~~判树,连通,带权
    C++ //练习 10.2 重做上一题,但读取string序列存入list中。
    缓存知识总结
    值类型与引用类型的区别,以及string类型的解释
    Java安全第一篇 | 反射看这一篇就够了
  • 原文地址:https://blog.csdn.net/dengfengling999/article/details/133012985