JVM 内存分配和回收策略 判断对象是否已死

一:介绍

内存管理解决的两个问题:给对象分配内存 和  回收分配给对象的内存;

二:内存分配图

包含新生代(Eden区和两个surivivor区,默认比值为8:1),老年代 和 永久代;

三:对象分配的策略

1-对象优先在Eden分配

   当Eden区没有足够的空间时,虚拟机会发起一次Minor GC。在其内部的对象大部分是朝生夕灭,回收较频繁,内存占用也少。一般是Full GC的10倍以上。

   新生代采用复制算法收集内存;

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

  大对象需要大量连续内存空间,应该尽量减少朝生夕灭的大对象。

3-长期存活的对象将进入老年代

   每一次Minor GC,其存活的对象年龄就会增加1。默认下15岁会晋升为老年代中。

4-动态分配年龄判断

   Minor GC过程是Eden区+一个survivor=另一个survivor,这样可能会出现存活的对象的内存大于surivivor,这样的话,就会提前把年龄小于15的对象晋升为老年代。必须保证surivivor能存储所有保留在新生代的所有内存之和。

5-空间分配担保

  在Minor GC前,先判断其老年代的内存空间;

  如果老年代最大可用的连续空间>新生代所有对象空间,则直接Minor GC;

  如果老年代最大可用的连续空间<新生代所有对象空间,则查看担保值,允许,则直接Minor GC;

  如果老年代最大可用的连续空间<新生代所有对象空间,则查看担保值,不允许,则先Full GC再Minor GC;

四:垃圾回收算法

1  标记-清除算法

   原理:分为标记和清除两个阶段,首先标记出所有需要回收的算法,再统一回收所有被标记的对象。

  不足:(1)效率不高,标记和清除两个过程的效率都不高;

            (2)空间问题,会出现很多空间碎片,可以大点的对象都不能找到足够的内存进行分配;

2  复制算法

   原理:将可用的对象分为两部分,每次只使用其中的一部分。当内存用完,将存活的对象复制到另外一块上面,然后清理使用过的一部分;

   优点:实现简单,运行高效;

   缺点:内存浪费,对象较多较大时效率会变低。

   Minor GC就是使用了复制算法,只是使用了三部分进行了优化;

3  标记-整理算法

   原理:和标记-清理算法相似,只是会把存活的对象全部已到一端,这样会有大片的连续内存空间;

   Full GC使用的就是标记-整理算法。

4  分代收集算法

   使用了上面的三种算法,就典型的应用就是整个JVM的垃圾回收机制。

五 如何判断对象已死

1-引用计数法:给每一个对象添加一个引用计数器,每当有一个地方引用它时,计数器值加 1;每当有一个地方不再引用它时,计数器值减 1,这样只要计数器的值不为 0,就说明还有地方引用它,它就不是无用的对象。缺点就是相互调用时,此种方法就判断不了了。

2-可达性分析:GC Roots,垃圾收集的起点。当一个对象到 GC Roots 没有任何引用链相连(GC Roots 到这个对象不可达)时,就说明此对象是不可用的,是死对象。

3-方法区回收:上面说的都是对堆内存中对象的判断,方法区中主要回收的是废弃的常量和无用的类

判断常量是否废弃可以判断是否有地方引用这个常量,如果没有引用则为废弃的常量。

参考文献:深入理解java虚拟机

图片来自:http://www.importnew.com/16173.html

原文地址:https://www.cnblogs.com/parent-absent-son/p/10145711.html