原创不易,尊重作者,转载请注明出处
前言:
简单来说,JVM会通过算法先判断哪些对象需要被回收,在合适的时机再通过算法进行回收。
1、JVM怎么确定哪些对象应该进行回收?
通过两个算法:引用计数法、可达性分析算法
引用计数法:给每个对象添加一个引用计数器,每次引用该对象时,计数器的值就加1,当引用失效时,计数器的值就减1,如果某个对象的计数器的值为0,那么这个对象就会被GC回收。
可达性分析算法:通过判断对象的引用链是否可达来决定对象是否可以被回收,可达性分析算法是从离散数学中的图论引入的,程序把所有的引用关系看作一张图,通过GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则说明这个对象不可用,就会被GC回收。
2、JVM会在什么时候进行回收?
1).CPU空闲的时候自动进行回收
2).堆内存存储满之后进行回收
3).主动调用System.gc()后进行回收
3、如何回收(垃圾回收的算法)?
通过4个算法:标记-清除算法、标记-整理算法、复制算法、分代收集算法
1).标记-清除算法:分为两个步骤,第一个步骤为标记,利用可达性分析算法遍历内存,把“存活”对象和“垃圾”对象进行标记,第二步是清除,再遍历一次内存,把所有“垃圾”对象所占用的空间直接清除。
回收前 回收后优点:简单
缺点:容易产生内存碎片
2).标记-整理算法:分为两个步骤,第一个步骤也是将“存活”对象和“垃圾”对象进行标记,第二个步骤是清除所有的“垃圾”对象后,再将“存活”的对象进行整理。
回收前 回收后优点:不会产生内存碎片
缺点:需要整理的过程
3).复制算法:将内存按照容量划分为大小相等的两块,每次只使用其中的一块,当这一块用完后,就将还“存活”的对象复制到另一块上,然后再把使用过的内存空间一次性清除掉。
回收前后优点:简单、不会产生内存碎片
缺点:内存利用率太低,只用了一半
4).分代收集算法:它本身不是一种新的算法,而是一种智能的算法,JVM会把内存分为三个区域,新生代、老年代和永久代,然后自动选择之前的三种算法进行垃圾对象回收。
新生代:新生代的目标是尽可能快速的收集掉那些生命周期短的对象,一般情况下,所有新生成的对象首先都是放在新生代。
老年代:老年代存放的都是一些生命周期较长的对象,比如在新生代中经历了很多次垃圾回收后仍然存活的对象就会被放到老年代中。
永久代:永久代主要用于存放静态文件。
结论:
⑴新生代主要使用复制算法
⑵老年代主要使用的标记-清除或标记-整理算法
⑶在jdk8的时候永久代已经被废弃,因为永久代内存经常不够用或发生内存泄露,从而出现OOM异常,因此Java提供了与永久代类似的“元空间”技术,“元空间”的本质和永久代类似,但是“元空间”并不在虚拟机中,而是使用的本地内存,也就是不局限与JVM可以使用的系统的内存。
网友评论