垃圾回收概念和其算法
垃圾回收(Garbage Collection 简称GC) GC中的垃圾,特指存在内存中,不会再被使用的对象,而回收就是相当于把垃圾“倒掉”。垃圾回收有很多种算法:如引用计数法、标记压缩法、复制算法、分代、分区的思想
引用计数法:
古老而经典的垃圾收集算法,核心就是在对象被其他所引用时计数器加1,而当引用失效时则减1,但是会存在一个严重的问题:无法处理循环引用的情况,而且每次进行加减操作会浪费系统的性能。
标记清除法:
就是分为标记和清除两个阶段进行处理内存中的对象,当然这种方式也是有非常大的弊端,就是空间碎片问题,垃圾回收后的空间不是连续的,不连续的内存空间工作效率要低于连续的内存空间
复制算法:
其核心思想就是将内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存留对象赋值到未被使用的内存块中,之后去清除之前正在使用的内存块中所有对象,反复去交换连个内存的角色,完成垃圾收集。
(java中新生代的from和to就是使用这个算法)
标记压缩法:
标记压缩法在标记清除法的基础上做了优化,把存活的对象压缩到内存一端,而后进行垃圾清理。(java中老年代使用的就是标记压缩法)
考虑:为什么新生代和老年代使用不同的算法
新生代对象死的快
分代算法:
就是根据对象的特点把内存分成N块,而后根据每个内存的特点使用不同的算法。对于新生代和老年代来说,新生代回收频率很高,但是每次回收耗时都很短,而老年代回收频率较低,但是耗时会相对较长,所以应该尽量减少老年代的GC。
分区算法:
其主要就是将整个内存分为N多个小的独立空间,每个小空间都是可以独立的,这样细粒度的控制一次回收都是单个小空间,而不是对整个空间进行GC,从而提升性能,并减少GC的停顿时间。
分区算法 oracle收购后尝试的垃圾回收时的停顿现象
垃圾回收器的任务是识别和回收垃圾对象进行内存清理,为了让垃圾回收器可以高效的执行,大部分情况下,会要求系统进入一个停顿的状态。
停顿的目的时终止所有应用线程,只有这样系统才不会有新的垃圾产生,同时停顿保证了系统状态在某一个瞬间的一致性,也有益于更好的标记垃圾对象。因此在垃圾回收时,都会产生应用程序的停顿