java 虚拟机

来源:互联网 发布:轻松赚钱的软件 编辑:程序博客网 时间:2024/06/02 04:11


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

1.哪些内存需要回收

    判断哪些对象还存活,主要有两个方法:1.引用计数法:存在对象之间相互循环引用的问题。2:可达性分析算法:将GC-Roots的对象作为起点,当一个对象到GC-Roots没有任何引用链相连,则 此对象是不可用的。

   GC-Roots的对象包括下面几种:

1.虚拟机栈中引用的对象

2.方法区中类静态属性引用的对象

3.方法区中常量引用的对象

4.本地方法栈中引用的对象

 2. 垃圾收集算法:

 1. 标记—清除算法:分为标记与清除两个阶段,首先标出所有需要回收的对象,在标记完成后统一进行回收。

    缺点:一个是效率问题,标记和清除两个过程的效率不高,另一个是空间问题,标记清除之后会产生大量不连续的内存碎片。

2.复制算法:为了解决效率问题吗,他将内存容量分为大小相等的两块,每次使用一块,当这一块的内存用完后,就将还存活的复制到另外一块上,然后一次性清理掉已经使用过的内存。一般新生代采用这种算法

缺点:内存缩小了一半,还有就是对象存活率较高时就需要较多的复制,效率将会变低。

3.标记--整理算法:让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

4.分代收集算法: 把java堆分为新生代和老年代,新生代采用复制算法,老年代采用标记--清理算法

HotSpot 的算法实现:

使用OopMap的数据结构记录下栈和寄存器中哪些位置时引用,通过设置安全点,只有在安全点处开始GC,采用主动式中断,设置一个标志,各个线程执行时主动去轮询这个标志,发现中断标志为真是就中断自己。当有线程挂起时,需要使用安全区域方法。

3.内存分配与回收策略

1. 对象优先在Eden分配

   如果新对象内存不足时,将发生MinorGC,如果另外一个Survivor没有足够的内存,通过分配担保机制提前转移到老年代去。

   大对象直接进入老年代,提供了一个-XX:PretenureSizeThreshold参数,大于这个设置值的对象将直接进入老年代。

   长期存活的对象将进入老年代。虚拟机给们给每个对象定义了一个对象年龄计数器,没经过一次MinorGC后加一,默认15,大于之后就会被晋升到老年代中,如果Survivor空间中相同年龄所有对象大小的总和大于Survivor空间一般,那年龄大于或等于该年龄的将直接进入老年代。

     空间分配担保, 在发生Minor GC 之前,虚拟机要检查老年代最大可用连续空间是否大于新生代所有对象总空间,如果成立,那么Minor GC 不会有风险。因为Minor GC 后仍有大量的对象存活的话,Survivor吗,没有足够的空间作为轮换备份,就需要老年代进行分配担保,把Survivor无法容纳的对象直接进入老年代。如果担保失败需要进行一个Full GC .

原创粉丝点击