那位先生

个人站

前世五百次回眸,才能换得今生的一次擦肩而过。


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

1.对象已死吗?

1.判断方法

判断一个对象是否死亡的方法:引用计数算法和可达性分析算法。
引用计数算法:给对象添加一个引用计数器,有一个地方引用它就给它+1,引用失效就-1,当值为0表示引用已失效。缺点:无法解决对象之间相互引用的问题。
可达性分析算法:通过一系列的称为“GC Roots”的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有 任何引用链相连时,则证明此对象是不可用的。

2.关于引用

JDK1.2后引用分为强引用、软引用、弱引用、虚引用。
强引用:例如:A a = new A();,只要强引用存在,垃圾收集器就永远不会回收掉被引用的对象。
软引用:用于描述有用但非必须的对象,它会在内存溢出前被回收。
弱引用:用于描述非必须的对象,它在下一次垃圾收集时被回收。
虚引用:无法通过虚引用取得对象实例。
各状态可达性关系图

3.tips

废弃常量的判断:没有任何地方引用该常量。
无用类的判断:1.java堆中不存在该类的任何实例;2.该类的类加载器已被回收;3.该类对应的java.lang.class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

2.垃圾收集算法

1.标记清除算法

过程:首先标记出所有要回收的对象,在标记完成统一回收所有被标记的对象。
缺点:效率不高;标记清除后产生大量不连续的内存碎片。

2.复制算法

过程:将可用内存按容量划分为大小相等的两块 ,每次只使用其中的一块。当这一块用完了,将就还存活的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。
优点:实现简单、运行高效;
缺点:内存利用率低,将内存的使用缩小一半。

3.标记-整理算法

过程:标记过程仍然与“标记-清除”过程一致,但后续步骤不是对可回收对象进行直接清理,而是让所有存活的对象都移动另一端,然后清理掉端边界以外的内存。

4.分代收集算法

java堆中分为新生代和老年代。新生代每次垃圾收集都有大量对象死去,存活的少量,因此采用复制算法;老年代对象存活率高,采用标记-清除或标记-整理算法。

3.垃圾收集器

各种垃圾收集器 垃圾收集器 如果两个收集器之间存在连线,说明他们可以搭配使用。

1.Serial

单线程的垃圾收集器,工作时会停掉其它线程。Client模式下默认的新声代收集器。

2.Serial Old

Serial的老年代版本,单线程,采用标记-整理算法。

3.ParNew</h4>

收集器的多线程版本,同样在其工作时会挺掉用户的其它线程。Server模式下虚拟机首选的新声代收集器。(除serial外唯一可以与CMS一起工作的新生代垃圾收集器)

4.Parallel Scavenge

并行的多线程垃圾收集器。他与CMS等的区别是,他们关心的尽可能的缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge则侧重于达到一个可控制的吞吐量。 (吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),吞吐量高可以高效率的利用CPU时间)。

5.Parallel Old

Parallel Scavenge的老年代版本,存在目的与Parallel Scavenge一起工作。因为Parallel Scavenge只能和Parallel Old以及Serial Old一起工作。

6.CMS

以获取最短停顿时间为目标的垃圾收集器。基于标记-清除的算法实现。
工作步骤:初始标记–>并发标记–>重新标记–>并发清除。 初始标记:标记GC–ROOTS能直接关联到的对象;并发标记:进行GC ROOTS tracing的过程; 重新标记:修正并发标记期间因用户程序继续运行而导致标记部分发生变动的标记。
注意:并发标记和并发清除期间可以和用户线程一同工作。
优点:并发收集、低停顿。
缺点:对CPU资源敏感;无法清理浮动垃圾;收集结束后产生大量空间碎片。

7.G1收集器

特点:
1.并发和并行:利用多个CPU来缩短停顿时间,通过并发方式在收集垃圾时不用停止其它线程。
2.分代收集:采用不同的方式去处理新创建的对象、已存活一段时间的对象以及熬过多次GC的对象。
3.空间整合:G1从整理看是基于“标记-整理”,从局部看是基于“复制”算法的实现。
4.可预测的停顿:比如说给你A秒的时间内,垃圾收集的时间不得超过B秒;
运行步骤: 1.初始标记:标记GC–ROOTS能直接关联到的对象,并修改ATMS的值。
2.并发标记:采用不同的方式去处理新创建的对象,已存活一段时间的对象和熬过多次GC的对象。
3.最终标记:修正并发标记期间因用户程序继续运行而导致标记部分发生变动的标记。
4.筛选回收:根据回收价值和成本对region排序,并根据用户期望的GC停顿时间制定回收计划;

8.各版本jdk的垃圾收集器

jdk1.7和1.8使用的是Parallel Scavenge和Parallel Old的组合;jdk1.9使用的是G1

4.内存分配与回收策略

自动内存管理:给对象分配内存以及回收分配给对象的内存。

1.分配策略

1.对象优先在Eden区分配:当Eden区没有足够空间时将触发一次Minor GC。
java堆的内存分配比例
2.大对象直接进入老年代。大对象:需要大量连续内存空间的java对象。参数标准:-xx:PretenureSizeThreshold,大于这个值的为大对象。一般来说有长字符串和数组。
3.长期存活的对象直接进入老年代。长期存活的对象:经历Minor GC次数:Eden 1次–>Survior n次的对象。n的参数定义:-xx MaxTenuringThreshold,通过这个参数设置。
4.Survior空间中n岁的对象大小总和大于空间的一半,则大于n岁的对象直接进入老年代,即使n小于参数设定的年龄。注:年龄的定义:对象从Eden区进入Survior区后,在Survior区经过一次Minor GC就是一岁。

2.空间分配担保

空间分配担保

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
你说多少就多少

比五毛钱特效专业哦