Jackyss

导航

 

1.如何确认垃圾

1.1引用计数器

  在Java中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单的方法是用通过引用计数来判断一个对象是否可以回收,即一个对象如果没有任何与之关联的引用,即她们的引用计数都不为0,则说明对象不太可能再被用到,那么这个对象就是可回收

1.2可达性分析(解决引用计数器中循环引用的问题)

  通过 一系列的“GC roots”作为起点搜索。如果在“GC roots" 和一个对象之间没有可达路径,则称该对象是不可达的,要注意的是,不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记,两次标记后仍然是可回收的对象,则将面临回收。

2算法

2.1 标记清楚算法(Mark-Sweep)

最基础的垃圾回收算法,分为两个阶段,标注和清楚。标记阶段标记出所有需要回收的对象,清楚阶段回收被标记的对象所占用的空间. 最大的问题就是内存碎片化严重,后续会发生大对象不能找到利用空间的问题

2.2复制算法(copying)

为了解决Mark-Sweep算法内存碎片化的缺陷而提出的算法,按内存的容量将内存划分为等大小的两块,每次只使用其中的一块,当这一块内存满后,将尚存活的对象转移到另一块上,把已使用的内存清理掉

这种算法,效率高,不会产生碎片,但是可用的内存被压榨为了一半,且存活对象增多的话,效率会大大降低

2.3标记整理算法(Mark-Compact)

结合上面两种算法,但是标记后,不清理对象,而是将存活对象移到内存的一端,然后清楚端边界外的对象。

2.4分代收集算法

 

 核心思想: 根据对象存活的不同生命周期将内存划分为不同的域,一般情况下将GC堆划分为老生代和新生代。

老生代的特点是每次垃圾回收时,只有少量对象需要被回收。

新生代的特点是每次垃圾回收时,都有大量的垃圾需要被回收,因此可以根据不同区域选择不同的算法

  2.4.1 新生代的复制算法

    JVM的GC对于新生代都采取Copying算法,因为新生代中每次垃圾回收都要回收大部分对象,即要复制的操作比较少,但通常并不是按照1:1来划分新生代的,一般将新生代划分为一块较大的Eden空间和两个较小的Survivor(from,to)每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将该两块空间中还存活的对象复制到另一块Survivor空间中。

 

   2.4.2老年代的标记比整理算法

    老年代每次只回收少量的对象,所以采用mark-compact算法

    1.java虚拟中的方法区的永久代,用来存储class类,常量,方法描述等。对永生代的回收主要包括废弃常量和无用的类。

    2.对象的内存分配主要在新生代的Eden Space和From Space,少数情况会直接分配到老年代

    3.当新生代的eden和from空间不足时就会发生一次GC,进行GC后,Eden和from区存活的对象会被挪到To中,然后将eden和from进行清理。

    4.如果to无法存储某个对象,则将这个对象存储到老年代。

    5.在进行GC后,使用的便是Eden和To,如此循环反复。

    6.当对象在躲过一个GC后,其年龄就会+1,默认达到15就会被移到老生代中。

 

posted on 2020-06-30 17:12  Jackyss  阅读(105)  评论(0)    收藏  举报