深刻理解java虚拟机-垃圾回收

当须要排查各类内存溢出,内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,咱们就须要对这些自动化的技术实施必要的监控和调节。java

       在前面一章了解到java内存的运行时区域,对于程序计数器,虚拟机栈,本地方法栈三个区域随线程而生,随线程而灭,且栈中的每个栈帧分配多少内存基本上是在类结构肯定下来时就已知的,所以,这几个区域的内存分配和回收都具有肯定性,所以不须要加多考虑。算法

      而java堆和方法区不同,一个接口中的多个实现类须要的内存可能不同,一个方法中的多个分支须要的内存也不同,咱们只有在程序处于运行期间时才能知道会建立哪些对象,这部分的内存分配和回收都是动态的,所以,垃圾收集器所关注的就是这部分的内存多线程

垃圾收集也叫GC,GC须要作如下三件事情:并发

1)如何断定对象为垃圾对象?高并发

 答:策略有引用计数法可达性分析法spa

2)如何进行垃圾回收?线程

 答:策略有:标记-清除算法复制算法标记-整理算法分代收集算法3d

        垃圾收集器有:Serial ,parnew,CMS,G1对象

3)什么时候进行垃圾回收?blog

 

 

如何断定对象为垃圾对象? 

1,引用计数法: 在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值+1,当引用失效的时候,计数器的值-1。

                      当值被判为0的时候就进行回收

存在问题:当对象进行循环引用时,致使他们的引用计数都不为0,就不能分析对象为垃圾对象

优势是比较灵活

 2,可达性分析法:经过一系列的名为“GC Roots” 的对象做为起点,从这些节点开始往下搜索,搜索所走过的路径成为引用链。当一个GC Roots到这个对象不可达时,则证实此对象是不可用的,此时会将该对象断定为垃圾对象。

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

     1)虚拟机栈(栈帧中的局部变量表)

     2)方法区的类属性所引用的对象

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

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

目前断定是否为垃圾的算法均是可达性分析算法

 

如何进行垃圾回收?

1,标记-清除算法:算法分为“标记”和“清除”两个阶段,首先标记出全部须要回收的对象,在标记完成后统一回收掉全部被标记的对象

    它的缺点:一个是效率问题,标记和清除的过程都不高,另外一个是空间问题,标记清除以后会产生大量不连续的内存碎片,空间碎片太多会致使,当程序在之后的运行过程当中须要分配较大对象时没法找到足够的连续内存而不得不触发另外一次垃圾收集的动做。

2,复制算法:针对新生代内存进行回收

解决标记-清除算法的效率问题,它将可用内存按容量划分为大小相等的两块,每次只使用其中一块,当这一块的内存用完了,就将还存活的的对象复制到另一块上面,而后再把已使用的内存空间一次清理掉

上述算法会引来一个新的问题:形成内存资源极大的浪费,咱们来按如下方法分配内存空间:

   将内存分为一块较大的Eden空间和两块较小的Servivor空间,每次使用Eden和其中的一块Servivor。当回收时,将Eden和Servivor中还存活着的对象一次性的拷贝到另一块Servivor空间上,最后清理掉Eden和刚才使用过的Servivor的空间

3,标记整理算法:针对老年代内存进行回收,也叫标记,整理,清除,整理阶段须要将存活对象排序整理好

4,分代收集算法:

对于新生代选择复制算法,对于老年代,选择标记整理算法

 

垃圾回收器:垃圾回收器就是垃圾回收的具体体现

介绍HotSpot JVM 1.6的垃圾收集器:两个收集器之间存在连线,就说明它们能够搭配使用

  Serial收集器:它是一个单线程的收集器,在它进行垃圾收集时,必须暂停其余全部的工做线程,直到它收集结束

                   它是虚拟机运行在client模式下的默认新生代收集器,有着优于其余收集器的地方:简单而高效,对于限定单个CPU的环境来讲,Serial收集器优                     于没有线程交互的开销,专心作垃圾收集天然能够得到最高的单线程收集效率。

  ParNew收集器:是Serial收集器的多线程版本,除了使用多线程进行垃圾收集以外,其他行为包括Serial收集器可用的全部控制参数,收集算法,对象分配规                      则,回收策略等都与Serial收集器彻底同样。

相关文章
相关标签/搜索