JVM-垃圾回收机制

垃圾回收主要发生在堆内存,从以下三个方面入手:

1,哪些内存需要回收?

2,什么时候回收?

3,如何回收?

 

首先先说下堆内存分配:

主要分为新生代和老年代:

新生代分为:Eden(8)区,from survivor(1)区,to survivor(1)区,进行minor gc的时候会在两个survivor左右复制,因此会有一个survivor区域的空间总是空置的。

老年代:主要存放大对象,发生的是full fc,会触发stop the world(STW机制,全部线程挂起)。

永久代也会触发垃圾回收,主要回收无用的常量和无用的类,当常量没有被任何地方引用,则会被回收,无用的类判断如下:

1,该类的所有实例对象都已被回收

2,加载该类的classloader已被回收

3,该类的java.lang.Class对象没有在任何地方被引用,无任何地方通过反射获取该类的方法。

 

1,哪些内存需要回收

1.1 引用计数法

这个方法已不再使用,在循环引用的情况下无法确认对象是否已死。

1.2 可达性分析算法

简单来说就是从GC Root一直找下去,有引用关系的则是存活对象,没引用关系的则对象可以被回收。

可以作为GC Root对象的有:

1,虚拟机栈(栈帧中的本地变量表)引用的对象;

2,方法区中的静态属性引用的对象;

3,方法区中的常量引用的对象;

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

2,什么时候回收

安全点与安全区域的概念

3,如何回收

垃圾回收算法主要分为以下三种:

1,复制算法:用在新生代

2,标记清除算法:用在老年代

3,标记整理算法:用在老年代

4,内存分配策略

1,对象优先在Eden区分配,如Eden没有足够的空间,虚拟机将会触发一次minor Gc。

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

3,长期存活的对象将进入老年代,对象在Survivor区域每经过一次minor gc,年龄就会增加一岁,年龄增加到一定程度(默认15岁),就会被晋升到老年代。

4,动态年龄判断,并不是所有对象达到了15岁才会晋升到老年代,如果survivor空间中相同年龄所有对象大小的总和大于survivor空间的一半,那么年龄大于或等于该年龄的对象会直接进入老年代。

5,空间分配担保,在发生minor gc之前,虚拟机会先检查老年代的最大可用的连续空间是否大于新对象的总空间,如果大于,则可以确保minor gc是安全的。如果小于,则虚拟机会先查看HandlePromotionFailure设置是否允许担保失败,如果允许,则虚拟机会检查老年代最大的可用连续空间是否大于历次晋升到老年代的对象的平均大小,如果大于,则尝试一次minor gc,如果小于或者不允许担保失败,那么此时将会进行full gc。

上一篇:Java虚拟机内存分配与回收策略


下一篇:[leveldb] Compaction