JVM只会在两个地方发生GC:堆区,方法区(较少)。
先说说方法区,当方法区(持久代)满了,会发生GC。
再说堆区,堆区的主要是对象回收,那么如何判定一个对象是不是该回收呢???这就引入JVM查找算法。
JVM查找算法:
1.经典的引用计数算法,当一个对象被引用一次,计数+1,失去引用,计数-1,当计数在一段时间为0之后,即可断定为可回收,不过这个算法不能解决相互引用的对象。
2.可达性算法(目前主流算法)
JVM会判定这个对象是否引用从而决定是否回收它,若从GC ROOT结点能一步步引用到这个对象,那么这个对象就不能回收,若无法引用到这个对象,那么就说明该对象可以回收。
那么JVM怎么回收呢?这就引入JVM常用GC算法。
JVM常用GC算法:
1.复制
内存分为两个区,对象的声明在一个区,GC时,把存活的对象放到另外一个区。这个做法,浪费内存,而且当对象存活率较高时这个方法显然很不合适。
2.标记——清除算法
遍历对象,把活着的对象标记起来,清除那些没有标记的对象。这就很容易导致内存碎片化。
3.标记——压缩算法
在清除算法之后,把这些对象整理到一块儿,然后更新他们的引用指针。
JVM内存分区
内存被分为:新生代、老年代、持久代(方法区,大多数JVM没有这个)。
新生代又分为Eden区和Survivor区,当Eden区不足时会把存活的对象转至Survivor区,当新生代进行垃圾回收时会发出minor GC也称Youn GC,老年代用于存放新生代多次回收依然存活的对象,当它满了会发生Major GC也称Full GC。