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

来源:互联网 发布:目前淘宝什么好卖 编辑:程序博客网 时间:2024/05/18 01:35

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

java和C++之间有一堵墙由内存动态分配和垃圾收集技术所围成得“高墙”,墙里面的人想进去,墙里面的人却想出来。:haha::haha:

引用计数算法

给对象中添加一个引用计数器,每当一个地方引用它时,计数器值就加一;当引用失效是,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。(不能解决对象相互循环引用的问题)

可达性分析算法

通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到达GC Roots没有任何引用链相连时,则证明此时对象是不可用的。如图所示,对象object 5,object 6,object 7虽然相互相连,但是他们和GC Roots是不可达的,所以可以判定为可回收对象。

TIM图片20171022200438

在java语言中,可作为GC Roots的对象包括下面几种:

虚拟机栈(栈帧中的本地变量表)中引用的对象。

方法区中静态属性引用的对象。

方法区中常量引用的对象

本地方法栈中JNI(即一般说的Native方法)引用的对象。

Java中引用的划分

Java中引用划分为四个级别:强引用,软引用,弱引用,虚引用四种。引用强度依次减弱。

强引用就是只在程序代码之中普遍存在,类似“Object obj = new Object()”这类的引用,只要强引用还存在,垃圾收集器就永远不会回收掉被引用的对象

软引用是用来描述一些还有用但并非必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。

弱引用也是用来描述非必须对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器开始工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。

虚引用也被称为幽灵引用,他是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时受到一个系统通知。在jdk1.2之后,提供了PhantomReference类来实现虚引用。

方法回收区

方法回收区主要回收两部分内容:废弃常量和无用的类。回收废弃常量和在堆中回收对象非常类似。以常量池中字面量的回收为例,假如一个字符串“abc”已经进入了常量池中,但是当前系统没有任何一个String对象叫做“abc”的,也就是说没有任何String对象引用常量池中的“abc”常量,也没有其他地方引用了这个字面量。如果发生垃圾回收,而且必要的话,这个“abc”常量就会被系统清理出常量池。常量池中的其他类(接口)、方法、字段的符号引用也与此类似。

如何判断一个无用的类:

1.该类的所有实例都已经被回收,也就是java堆中不存在该类的任何实例。

2.加载该类的ClassLoader已经被回收。

3.该类对应的java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的方法。

在大量使用反射,动态代理、CGLib等ByteCode框架、动态生成JSP以及OSGI这类频繁自定义ClassLoader的场景都需要虚拟机具备类卸载功能,以保证永久代不会溢出。

垃圾收集算法

标记-清除算法

首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。TIM图片20171022212759

复制算法

将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉。这样使得每次都是对这个半区进行内存回收,内存分配时也不需要考虑内存碎片的问题,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。

TIM图片20171022213143

标记-整理算法

标记过程和前面的算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界意外的内存。

标记-整理

分代收集算法

根据对象存活周期的不同将内存划分为几块。一般是吧Java的堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适合的算法。新生代采用复制算法。而在老年代中则采用标记-清理算法或者标记-整理算法。

关于Java中什么是新生代和老年代的疑问:

java中创建的对象都是放在java堆中的,方法区放置的是类的信息。其中java堆又可以分为新生代和老年代,默认创建的对象都是先放在新生代,当gc收集发生之后,若该对象没有没回收,并且达到了老年代的年龄,就被转移到老年代

HotSpot的算法实现

枚举根节点

安全点

安全区域

垃圾收集器

垃圾收集器

7种作用域不同分代的收集器,如果两个收集器之间存在连线,就说明他们可以搭配使用。虚拟机所处区域,则表示他是属于新生代收集器还是老年代收集器。

Serial收集器

Serial收集器是最基本,发展历史最悠久的收集器,曾经(在jdk1.3.1之前)是虚拟机新生代收集的唯一选择。大家看名字就知道,这个收集器是一个单线程的收集器,但它的“单线程”的意义并不仅仅说明她只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集是,必须暂停其他所有的工作线程直到它收集结束。

Serial收集器

ParNew收集器

ParNew收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数、收集算法、Stop The World、对象分配规则、回收策略等都与Serial收集器完全一样。ParNew收集器

Paraller Scavenge收集器

Parallel Scavenge收集器是一个新生代收集器,他也是使用复制算法的收集器,又是并行的多线程收集器。这个收集器关注的不是GC停顿时间,而是更关注吞吐量(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间))的大小。由于与吞吐量的密切关系,Parallel Scavenge收集器也被称为“吞吐量优先”收集器。

Serial Old收集器

Serial Old是Serial收集器的老年代版本,他同样是一个单线程收集器,使用“标记-整理”算法。这个收集器的主要意义也是在于给Client模式下的虚拟机使用。如果在Server模式下,那么他主要还有两大用途:一种用途是在JDK1.5以及以前的版本之中与Parallel Scavenge处理器搭配使用。另一种是作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用。

Serial收集器

Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。

![Serial Scavenge收集器](C:\Users\lenovo\Desktop\Serial Scavenge收集器.png)

CMS收集器

CMS收集器是一种以获取最短回收停顿时间为目标的收集器。CMS收集器是基于“标记–清除”算法实现的,他的运作过程相对于前面的几种收集器相对来说更为复杂一些。主要分为四个步骤:

初始标记

并发标记

重新标记

并发清除

初始标记、重新标记着两个步骤仍然需要“Stop The World”。初始标记仅仅是标记一下GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程。而重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。

由于整个过程中耗时最长的并发标记和并发清除过程都可以与用户线程一起工作,所以,总体上来说,CMS收集器的内存回收过程是与用户一起并发执行的。

CMS收集器

G1收集器

G1收集器是一款面向服务端应用的垃圾收集器。具体特点如下:

并行和并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-the-world停顿时间,部分其他收集器原本需要停顿java线程执行GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。

分代收集:与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但他能够采用不同的方式去处理新创建的对象和已经存活了一段时间,熬过多次GC的就对象已获得更好的收集效果。

空间整合:与CMS的“标记- 清理”算法不同,G1从整体来看是基于“标记-整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的,但无论如何,这两种算法都以为这G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前出发下一次GC。

可预测的停顿:这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同关注点,但G1除了追求低停顿之外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N秒,这几乎已经是实时java(RTSJ)的垃圾收集器的特征了。

G1收集器的运行大致可划分为一下几个步骤:

初始标记

并发标记

最终标记

筛选回收

原创粉丝点击