JVM GC垃圾回收和回收算法
概述
程序运行需要申请内存资源,线程执行结束后如果没有相应的回收会造成内存溢出,一般的高级OOP语言都带有Garbage Collecting垃圾回收机制
C/C++语言的回收
一般的高级OOP语言都带有Garbage Collecting垃圾回收机制,C语言采用malloc()分配堆内存。使用free释放内存。而C++采用new 和delete分配和释放。
Java语言的垃圾回收
java不需要程序员自己操作内存空间,而是使用JVM自带的垃圾回收机制完成。目前流行的Python C# go都有自己的垃圾回收机制
垃圾回收算法
引用计数法
引用计数法最早由Geore.E.Colins在1960首次提出,如今仍然在被使用
1.定义:引用指向对象是该对象引用计数器+1,引用失败时-1(如a=null)。如果A计数器为0,则说明该对象可以被回收。
2.特点
优点:
- 及时回收无效内存,实时性高
- 垃圾回收过程中无需挂起
- 没有全局扫描,性能高
缺点:
- 对象创建时需要更新引用计数器,耗费一部分时间
- 浪费CPU资源,计数器统计需要实时进行
- 无法解决循环引用问题,即使对象无效仍不会被回收
标记清除法
标记清除算法,是将垃圾回收分为2个阶段,分别是标记和清除。
标记:从根节点开始标记引用的对象。
清除:未被标记引用的对象就是垃圾对象,可以被清理。
标记压缩算法
标记压缩算法是在标记清除算法的基础之上,做了优化改进的算法。和标记清除算法一样,也是从根节点开始,对 对象的引用进行标记,在清理阶段,并不是简单的清理未标记的对象,而是将存活的对象压缩到内存的一端,然后 清理边界以外的垃圾,从而解决了碎片化的问题。
复制算法
复制算法的核心就是,将原有的内存空间一分为二,每次只用其中的一块,在垃圾回收时,将正在使用的对象复制 到另一个内存空间中,然后将该内存空间清空,交换两个内存的角色,完成垃圾的回收。
如果内存中的垃圾对象较多,需要复制的对象就较少,这种情况下适合使用该方式并且效率比较高,反之,则不适合
在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。
紧接着进行GC,Eden区中