• JVM之GC


    判断对象需要回收:1.引用计数法:给对象加上一个计数器,当有一个地方引用它,

                    计数器+1,引用失效时,计数器-1,当计数器为0时,判定该对象可回收

              此方法无法检测循环引用 导致内存泄漏

              

    //循环引用
    
    public class MyObject{
       public MyObject chlid;  
    }
    
    public class Main{
    public static void main(String[] args){
      MyObject o1 = new MyObject();
      MyObject o2 = new MyObject();
      o1.child = o2;
      o2.child = o1;    
    }
    }

             2.可达性算法:指通过称为GC-Roots的对象为起始点,从这些结点向下搜索,

                    当从GCRoots到这个对象不可达时,被判定为可收回的对象

                可作为GC ROOTs:栈中引用对象,方法区中静态属性和常量引用对象

    finalize()方法:  当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。

    四大引用:强:普遍存在,引用在就不回收引用对象

         软:softReference,有用非必须,内存溢出前回收

        

      String str = new String("aaa");//强引用
            SoftReference<String> softRef = new SoftReference<String>(str);//软引用

         弱:weakReference,非必须,下一次GC一定回收

         虚:phantomRenference,不能取得对象实例,为了回收时收到系统通知而设置

    回收方法区即永久代的回收:回收废弃常量(无对象引用)和

          无用的类(所有实例化,类加载器被回收,反射无法访问)

    回收算法:1.标记清除:先标记(可达对象)再清除,效率低,产生大量内存碎片,可能提前触发GC

         2.复制:内存分成两块,用一块,之后把存活对象复制到另一块,再把这块清理;

              回收新生代就是这个策略,但是具体分为3部分(8:1:1)

         每次使用Eden和其中一块Survivor区。也就是说新生代可用内存为新生代内存空间的90%。

         3.标记整理: 标记活的对象,让他们向一端移动,然后清理边界以外内存,用在老年代

          4. 分代:堆分为新生代,用复制,老生代用标记整理   GC有两种方式  Minor GC(针对新生代),Eden空间不足触发 和 Full GC(针对新生代和老生代)1.老年代空间不足,2.Minor GC晋升到老年代的平均大小大于老年代剩余空间 3.System.gc() 会触发

    stop the world: JVM由于要执行GC而停止了程序的执行  GC Roots可达性分析时,要使整个执行系统看起来像被冻结在某个节点,保证结果正确性

      虚拟机采用OopMap的数据结构直接得知哪些地方存着对象引用

    安全点:记录OopMap,程序中可安全进行GC的地方,选那些可让程序长时间执行的点,比如方法调用,循环,异常跳转

    GC发生时让所有线程跑到安全点的方法:抢占式中断(不用),暂停线程,恢复不在安全点的线程,让它们跑到安全点。

                      主动式中断:线程均设一个标志,轮询发现为真就挂起自己,轮询标志的地方就是安全点

    安全区域:引用关系不发生变化的区域,GC安全,“扩大的安全点”

    垃圾收集器:CMS:基于标记清除(老年代),极大缩短停顿时间  初始标记--并发标记--重新标记--并发清除(清理垃圾对象  程序不会停顿)

          G1: 分代收集,局部来讲基于复制,将堆划分多个区,跟踪每个区回收价值,维护优先列表  +  标记整理(减少碎片)

             初始标记---并发标记---最终标记--晒选回收

        其他:新生代的垃圾收集器有Serial(单线程)、

           ParNew(Serial的多线程版本)

          ParallelScavenge(吞吐量优先的垃圾收集器),

          老年代有SerialOld(单线程老年代)、

          ParallelOld(与ParallelScavenge搭配的多线程执行标记整理算法的老年代收集器)

     对象分配策略:.1.对象优先在Eden区分配

            2.大对象直接进入老年代

            3.长期存活的进入老年代

            4.Survivor区中相同年龄的所有对象大小的总和大于Survivor区空间的一半,

            年龄大于或等于该年龄的对象直接进入老年代

      

    空间担保分配:在发生MinorGC(回收年轻代)之前,HandlePromotionFailure允许担保失败,

          老年代最大可用连续存储空间小于新生代所有对象总空间,且大于历次晋升到

          老年代对象的平均大小,进行一次MinorGC,若不满足条件,改为FUllGC(堆及永久代)

    JDK命令:jps:列出正在运行虚拟机进程

           jstat:显示虚拟机进程中的类装载,内存,垃圾收集等数据。

           jinfo:查看调整各项参数  

           jmap:生成堆转储快照

  • 相关阅读:
    SWT 重启案例分析(二)
    SWT 重启案例分析(一)
    手机重启问题 Log 抓取方法
    手机重启问题快速分析定位指南
    SWT 手机重启问题分析指南
    属性动画 使用详解
    补间动画 使用详解
    帧动画 使用详解
    Android动画 使用详解
    Linux grep 命令大全
  • 原文地址:https://www.cnblogs.com/team42/p/7044926.html
Copyright © 2020-2023  润新知