zoukankan      html  css  js  c++  java
  • 垃圾回收算法

    垃圾回收的意义: 

      Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄漏,有效的使用空闲的内存。

    任何一种垃圾回收算法一般要做2件基本的事情:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。 

    对象存活判定算法:

      引用计数算法:每当一个地方引用一个对象,计数器就加1,引用失效的时候,计数器就减1。当计数器为0的时候就表示对象不会再被使用。

    缺点:难以解决对象之间相互循环引用的问题。

      可达性分析算法(主流):用过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,

    当一个对象到GC Roots没有任何引用链相连时,则此对象是不可用的。

     

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

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

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

      方法区中的常量引用的对象。

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

     

      不过那些发现不能到达 GC Roots 的对象并不会立即回收,在真正回收之前,对象至少要被标记两次。当第一次被发现不可达时,该对象会被标记一次,同时调用此对象的 finalize()方法(如果有);在第二次被发现不可达后,对象被回收。利用 finalisze() 方法,对象可以逃离一次被回收的命运,但是只有一次。逃命方法如下,只要在 finalize()方法中让该对象重引用链上的任何一个对象建立关联即可。而如果对象这时还没有关联到任何链上的引用,那它就会被回收掉。

     

    垃圾回收算法:

      标记-清除算法

      标记阶段:首先从根对象开始进行遍历,对从根对象可以访问到的对象都打上一个标记。

      清除阶段:对堆内存从头到尾进行线性的遍历,如果发现某个对象没有标记为可达对象,则就将其回收。

      缺点:效率不高。标记清除后会产生大量不连续的内存碎片。空间碎片太多会导致以后分配较大对象时,需要提前触发一次垃圾回收。

      复制算法:用于回收新生代。将一块内存上还存活的对象复制到另一块上,再一次清除之前的那块。

      通常用一块较大的Eden空间,和两块较小的Survivor空间。每次使用 Eden 和其中的一块 Survivor。

      当回收时,将 Eden 和 Survivor 中还存活的对象一次性拷贝到另外一块 Survivor 空间上,最后清理掉 Eden 和刚才用过的 Survivor 空间。

      Hotspot 虚拟机默认 Eden 和 Survivor 的大小比例是8:1,也就是每次新生代中可用内存空间为整个新生代容量的90%(80% + 10%),只有10%的内存是会被“浪费”的。

      缺点:存在空间浪费。

      标记-整理算法:用于回收老年代。标记后,让存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

      缺点:GC暂停时间增长。

      分代收集算法:将java堆分为新生代和老年代,新生代只有少量存活,采用复制算法。而老年代有大批存活,所以采用标记-整理算法或者标记-清除算法。

      增量回收算法如果一次性将所有的垃圾进行处理,需要造成系统长时间的停顿,那么就可以让垃圾收集线程和应用程序线程交替执行。

      每次,垃圾收集线程只收集一小片区域的内存空间,接着切换到应用程序线程。依次反复,直到垃圾收集完成。

      缺点:使用这种方式,由于在垃圾回收过程中,间断性地还执行了应用程序代码,所以能减少系统的停顿时间。

      但是,因为线程切换和上下文转换的消耗,会使得垃圾回收的总体成本上升,造成系统吞吐量的下降。

  • 相关阅读:
    MIB Browser使用方法
    RestTemplate调用https接口跳过证书验证
    Looper&Handler
    Thread类以及常见得同步类
    Android 关键类(RefBase,sp, wp)
    JNI
    binder
    struct enum union区别
    Q_PROPERTY
    linux 命令
  • 原文地址:https://www.cnblogs.com/mengchunchen/p/7819926.html
Copyright © 2011-2022 走看看