垃圾分类,从我做起-----论JVM的自我修养

 

GC根本目的:从内存中剔除死掉的对象。

判断一个对象是否死亡主要有两种方式:

可达性分析:从GC Roots开始向下搜索,搜索所走过的路径为引用链。当一个对象到GC roots没有任何引用链相连时,则证明此对象不可用,为不可达对象。

引用计数: 每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。

GC Roots包括:

  虚拟机栈中引用的对象。

  方法区中类静态属性实体引用的对象。

  方法区中常量引用的对象。

  本地方法栈中JNI引用的对象。

JVM 堆内存划分:

  新生代(Young Generation):新对象和没达到一定年龄的对象都在新生代。由  伊甸园 存活区  伸缩区组成,

  老年代(Old Generation):被长时间使用的对象在老年代。由 老年区 伸缩区组成

  元空间(Meta Space):由 元空间 伸缩区组成

GC过程:

  • 新对象产生,为该对象进行内存空间的申请。

  • 判断  伊甸园区  是否有内存空间,如果此时有充足内存空间,则直接将新对象保存到伊甸园区。

  • 如果  伊甸园区  内存空间不足, 执行Minor GC操作,清理Eden 不活跃对象。继续判断 伊甸园区 空间是否充足?如果充足,则将新的对象直接在伊甸园区进行内存空间分配。

  • 如果  伊甸园区  空间依然不足,判断 存活区 有无剩余空间,有则将伊甸园区的部分活跃对象保存在存活区,继续判断  伊甸园区 内存空间是否充足,如果充足,则进行内存空间分配。

  • 如果  存活区也  没有内存空间了,判断老年区是否空间充足,是则将存活区中的活跃对象保存到老年区,将伊甸园区将部分活跃对象保存地存活区中,再在伊甸园区为新对象分配内存空间。

  • 如果  老年代也 没有存储空间了,那么Major GC(Full GC)。然后再将存活区中的活跃对象保存到老年区,再将伊甸园区的部分活跃对象保存到存活区,最后在伊甸园区为新对象分配内存空间。

  • 如果  执行Full GC之后,依然空间依然不足,会产生OOM(OutOfMemoryError)异常

垃圾回收算法:  

  1. 标记/清除
  2. 复制
  3. 标记/整理

   新生代采用的是“复制”算法 ,老年代采用的是“标记/清除” 或者 “标记/整理”。

垃圾收集器:

  新生代收集器:

  1. Serial:单线程,主要是给Client模式下的JVM用
  2. ParNew:支持多线程
  3. Parallel Scavenge: 采用复制算法,支持多线程

  老年代收集器:

  1. Serial Old:采用 标记/整理 算法 ,单线程,主要是给Client模式下的JVM用
  2. Parallel Old: 采用 标记/整理算法  ,支持多线程
  3. CMS(Concurrent Mark Sweep):采用 标记/清除算法 ,支持并发  

 



 

posted @ 2019-11-11 17:06  Mr6  阅读(183)  评论(0编辑  收藏  举报