gc

程序运行时会有一个运行数据区来管理内存,它主要包括五个部分:1:程序计数器,2:虚拟机栈,3:本地方法栈,4:堆(Heap),5:方法区。
而其中程序计数器,虚拟机栈,本地方法栈是线程私有的,随线程而生,随线程而亡。
但方法区和堆不同,我们只有在程序运行期间才会知道创建哪些对象,这部分的内存的分配和回收都是动态的,GC主要关注这部分内存。
我们一般讨论的垃圾回收只要针对堆内存中的新生代和老年代。因为新生代和老年代结构的不同,所以使用不同的回收算法,针对新生代只要使用复制算法,
老年代使用标记-清除算法或标记-整理算法。

1.复制算法
复制算法的思想是将内存分成大小相同的两块,每次使用其中的一块,当这块内存用完了,就将还存活的对象复制到另一块区域内,然后对该快内存进行回收。
实际情况新生代中大部分对象的存活期都很短,所以并不需要按1:1来划分新生代,通常的做法是将新生代划分成一块大的Eden区和两块小的Survivor区,两块Survivor区的
大小相同,每次使用Eden区和其中的一块Survivor区,当回收时把存活的对象复制到另一个Survivor区,最后清除Enen区和Survivor区,如果用户复制的Survivor区存不下存活的对象
时,会放入老年代。
算法示列图如下:

2.标记清除算法
分两阶段1:标记,2:清除,
在标记阶段需要标记出需要回收的对象空间,在清除阶段清除之前打了标记的内存。这中算法有两个主要问题,1:标记和清除效率不高,2:清除后会产生很多部连续的
内存碎片,这样会导致在分配大对象时无法找到足够的连续的内存而触发另一次垃圾回收动作。
算法示列图如下:

3.标记整理算法
标记整理算法有效的预防了标记清除算法可能产生的大量不连续碎片的问题,在标记需要回收的对象后,它会将所有存活的对象挪到一边,然后再执行清理。
算法示列图如下:

posted @ 2018-01-05 18:36  宅山仔  阅读(295)  评论(0编辑  收藏  举报