垃圾回收机制概述
垃圾回收机制主要完成下面两件事情:
>>跟踪并监控每个Java对象,当某个对象处于不可达状态时,回收该对象所占有的内存
>>清理内存分配、回收过程中产生的内存碎片
垃圾回收的基本算法
对于一个垃圾回收器的设计算法来说,大致有如下可供选择的设计
串行回收就是不管系统有多少个CPU,始终只有一个CPU来执行垃圾回收操作;并行回收就是把整个回收工作拆分成多部分,每个部分由一个CPU负责,从而让多个CPU并行回收。并行回收效率高,但会增加内存碎片。
Stop-the-world的垃圾回收方式在执行垃圾回收的同时会导致应用程序暂停,并发执行垃圾回收需要解决和应用程序的执行冲突(应用程序可能会在垃圾回收过程中修改对象)。
为了减少内存碎片,支持压缩的垃圾回收器会把所有的可达对象搬迁到一起,然后将之前占用的内存全部回收。
不压缩的垃圾回收器只是回收内存,这样回收回来的内存不可能是连续的,因此将会有较多的内存碎片。
复制垃圾回收将会把所有的可达对象复制到另一块相同的内存中,这样虽能避免产生内存碎片,但是需要复制数据占用额外的内存
下面再详细介绍一下压缩,不压缩和复制三种垃圾回收方式
>>复制:将堆内存分成两个相同的空间,从根开始访问每一个关联的可达对象,将空间A的可达对象全部复制到空间B,然后一次性回收整个空间A
优点:操作简单成本小
缺点:占用较多额外内存
>>标记清除(mark-sweep):也就是不压缩回收方式。垃圾回收器先从根开始访问所有的可达对象,将其标记为可达状态,然后再遍历一次整个内存区域,对所有没有标记为可达的对象进行回收处理
优点:无需开辟新的内存,内存利用率高
缺点:需要遍历两次内存空间,遍历成本大,造成应用程序暂停的时间随遍历空间增大而线性增大;回收回来的内存不连续,产生较多内存碎片
>>标记压缩(mark-sweep-compat):这是压缩回收方式,这种方式充分利用以上两种算法的优点,垃圾回收器先从根开始访问所有的可达对象,将它们标记为可达状态。接下来垃圾回收器将这些标记对象搬迁到一起,这个过程被称为内存压缩,然后再回收那些没有标记的对象,这样避免了内存碎片的产生