JVM_Garbage Collection

 Garbage Collect(垃圾回收)

  如何确定一个对象是垃圾

          1.  引用计数

               判断当前应用程序中,只要还持有当前对象的引用,就代表该对象不是垃圾.如果没有任何指针指向其引用,它就是垃圾

               缺陷: 当两个对象循环依赖 ,互相持有对象的引用,那么采用此方法就无法判断出当前两个对象是垃圾

          2. 可达性分析

               从一个GC Root 出发 ,如果能够到达一个对象 ,那么久证明此对象不是垃圾

               可作为GC Root的有 : 方法区的静态变量,常量,虚拟机栈的局部变量表(栈帧内存储)等

   垃圾回收算法

            1. 标记--清除

                   缺点: 会产生大量的空间不连续碎片

            2. 复制                 

            3. 标记整理

 a : 对于堆的young区而言, 算法采纳 复制. 因为一个web项目大部分对象都是朝生夕死,线程结束,就像就变为垃圾.所以其实存活下来复制到S0或者S1的对象并不多,所以采用此算法

 b : 对于堆的old区而言,标记清除或标记整理(Old区对象存活时间比较长,复制来复制去没必要,不如做个标记再清理)

 线程结束,对象就变为垃圾 :  因为栈是随着线程的结束而结束, 如 Person person = new Person(),存储于局部变量表中的 person 随着线程消失就不存在了,那么存放于堆中的Person实例就不存在有人会指向它的引用,符合成为垃圾的标准,即下一次GC就可以清除掉了. 感觉与cookie和session比较相似,当浏览器关闭,cookie消失,其实session并未消亡,除非session过期时间到了或者调用方法让其直接消亡.否则它还是存在的,只是没有cookie能指向它了.

垃圾收集器类型

       G1 : 既适用于young 也适用于old区.

        特点:

        a : 可预测的停顿 : 在于此收集器可以设置停顿时间,但是不要太严格. (也就是用户可以设置程序的GC时间,即使垃圾未全部GC结束,也要停止)        

        b: 采用G1收集器时,Java堆的内存布局与其他收集器不同,逻辑上 old区, young区, S0 和S1 还是存在的,但物理上已经被分成一个个大小相等的独立区域(Regison) ,新生代和老年代已经不是物理隔离的了.并且可以不连续

理解JVM调试中常说的吞吐量和停顿时间

           吞吐量 : 运行用户代码时间 / 运行用户代码时间 + GC时间               (运行用户代码时间越大,其实这个值也就越大)

           a : 吞吐量越大,高效利用cpu,只要运用于后台的运算,而不需要过多的与用户交互

           停顿时间 : 垃圾收集器进行拉垃圾回收,终端应用执行响应时间.

            a : 停顿时间越短,越适用于web端与用户的交互,较快的响应速度带来极好的用户体验.

 

如何选择一个垃圾收集器

       官网说明:  https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#sthref28

   

猜你喜欢

转载自www.cnblogs.com/liweibing/p/12706817.html
今日推荐