垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制。在C语言中,通过malloc 和free申请并释放内存,在C++中,程序员通过new和delete方式申请释放内存。手动申请释放内存的优势在于执行效率更高,但是也存在一定的缺点;JVM通过垃圾回收器回收,很大程序提高了开发效率,不过降低了程序的执行效率。
确定内存中的垃圾对象的方法:
1、引用计数法
2、可达性分析法
可达性分析法通过一系列名为GC Roots的对象作为起点,从这些节点往下搜索,搜索走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时(意味着GC Roots到这个对象不可达),证明该对象是不可用的,则应该被回收。
GC Roots主要包括:
(1)虚拟机(JVM)栈中引用对象
(2)方法区中的类静态属性引用对象
(3)方法区中常量引用的对象(final 的常量值)
(4)本地方法栈JNI的引用对象
垃圾回收算法主要包括:
(1)标记-清除算法
标记清理算法有两步:1、标记内存中回收对象 2、回收标记对象的内存空间
该算法效率较低,且会产生内存碎片化问题
(2)复制算法
复制算法将内存划分为大小相等的两块,每次只使用其中的一块内存。当这A内存用完了,就将还存活的对象复制到B块上面,然后把A块的内存空间一次性清理掉
复制算法的效率跟存活对象的数量有很大关联,若存活对象很多,那么效率将大大降低,且可用空间为原来分配内存的一半
(3)标记-整理算法
完成标记后,不直接清理可回收对象,而是将存活对象全部向一端移动,接着清理掉边界以外的内存。
(4)分代收集算法
分代收集算法核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。将其分为年轻代、老年代和永久代。然后根据不同的区域采用合适的收集算法。
新生代使用复制算法、老年代使用标记-整理算法
常见的垃圾收集器
1、Serial收集器
2、ParNew收集器
3、Parallel Scavenge收集器
4、Serial Old收集器
5、Parallel Old收集器
6、CMS收集器
7、G1 收集器
volatile关键字的作用
1、线程可见性:使用volatile 修饰的变量,任何线程对其操作都是在主内存中进行的,不会产生变量副本,从而保证共享变量的可见性
2、通过内存屏障防止指令重排序