垃圾收集器和内存分配策略

http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29632145&id=4616836

http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html

以上是两个写的特别好的博客

在java内存运行时区域的各个部分中:程序计数器,虚拟机栈,本地方法栈随线程生和灭,

对于java中的堆和方法区,、只能在程序运行期间才知道会创建哪些对象,这部分内存的分配和回收是动态的,垃圾收集器所关注的主要是这部分内存。

哪些内存需要回收?

什么时候回收?

如何回收?

垃圾收集器对堆进行回收前需先确定哪些对象已经死去(不可能再被任何途径使用的对象)

一般的方法是给对象中添加一个引用计数器,即引用计数算法来管理内存,但是jvm并没有,因为无法解决对象之间相互循环引用的问题。

1:可达性分析

GC Roots

当一个对象到GC Roots没有任何引用链相连时,表明此对象不可达。

四种引用:强引用,软引用,弱引用,虚引用

强引用:类似于new对象的方式,只要强引用还在,GC永远不会回收被引用的对象

软引用:还有用,但非必须。在系统发出内存溢出之前,GC将这些对象列入回收范围进行第二次回收

弱引用:只能生存到下一次垃圾收集之前,无论内存是否足够,都会被回收

虚引用:唯一目的在对象被GC回收时受到一个系统通知。

如果对象在进行可达性分析时发现没有GC Roots相连的引用链,该对象会被第一次标记并且进行一次筛选,筛选条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finali或者finalize方法被虚拟机调用过,jvm都将这两种方式视为没有必要执行。

如果有必要执行,该对象会被放入一个叫做F-Queue队列中,稍后虚拟机自动创建一个低优先级的finalizer线程去执行它,即触发这个方法。稍后GC会对F-Queue中对象进行第二次小规模标记,如果通过finalize拯救了自己,则被移除出即将回收集合,否则就真的被回收

方法区的GC包括:jvm规范中说过可以不要求jvm在方法区实现垃圾收集

永久代垃圾回收的两个主要内容:废弃常量和无用的类

 3:垃圾收集算法

标记清除算法

首先标记所有需要回收的对象,在标记完成后统一回收所有被标记的对象

不足:效率问题,大量不连续的内存碎片

复制算法

将内存按容量比例划分成两块,只使用一块,当这一块用完,将还存活着的对象复制到另一块上,可实现整个半区的内存回收,不考虑内存碎片。但是可使用的内存缩小

标记整理算法

首先和标记清除算法一样标记处可回收对象,其次让所有存活对象移到一端,然后直接清理掉端边界以外的内存。

分代收集算法

在新生代,每次垃圾回收都有大量对象死去,只有少量存活,可考虑复制算法,而老年代,可考虑标记清理或标记整理算法

 GMS收集器

是一种以获取最短回收停顿时间为目标的收集器。

运作过程分为四步:

初始标记

并发标记

重新标记

并发清除

原文地址:https://www.cnblogs.com/gracyandjohn/p/4631635.html