zoukankan      html  css  js  c++  java
  • <正则吃饺子>:关于java中垃圾回收技术的简单学习总结

    知识介绍来自网络,后面会根据继续学习进行补充和适当的修改,谢谢!原文地址:http://www.importnew.com/26821.html#comment-578355

    java中的垃圾回收机制让开发者无须关注空间的创建和释放,它以守护进程的方式在后台自动回收垃圾。这样不仅提高了开发效率,还改善了内存的使用状况。

    一、主要涉及的问题:

    1)什么是堆内存?

    2)什么是垃圾?

    3)回收垃圾的方法有哪些?

    4)什么是分代回收机制?

    二、问题简要作答

    1、什么是堆内存?

      其在jvm启动时创建,主要用来维护运行时数据(动态数据),如运行过程中创建的(new出来的)对象和数组都是存在这块区域中。

      java中堆是非常重要的,如果我们动态创建的对象没有得到及时的回收,继续堆积,就会造成堆空间被占满,内存溢出。因此,java提供了一种垃圾回收机制,在后台创建一个守护进程,在内存空间紧张的时候,自动跳出来,把堆空间的垃圾全部回收出来,

      以保证程序的正常运行。

      补充http://www.cnblogs.com/zhengzeze/p/6519760.html (<正则吃饺子>:关于java中对内存部分的简单总结整理

    2、什么是垃圾?

      其指的是 不再存活的对象。

      常见的判断方法有:引用计数法 和 可达性分析法。

      引用计数法:为每个创建的对象分配一个引用计数器,用来存储该对象被引用的次数。当该个数为零,意味着没有人再使用这个对象,可以认为“对象死亡”。但是,这种方案存在严重的问题,就是无法检测“循环引用”:当两个对象互相引用,即时它俩都不被外界任何东        西引用,它俩的计数都不为零,因此永远不会被回收。而实际上对于开发者而言,这两个对象已经完全没有用处了。

            因此,java中没有采用这个方案来检测对象的存活性。

     可达性分析法:这种方案是目前主流语言判断对象存活性的方式。基本思路是把所有引用的对象想象成一棵树,从树的根结点 GC Roots 出发,持续遍历找出所有的连接对象,这些对象,就称为“可达”或者“存活”对象。其余的对象则被视为“死亡”的“不可达”对象,或称           “垃圾”。

            补充GC Roots是什么?  (参考:http://www.importnew.com/26821.html#comment-578355

            我们可以猜测,GC Roots 本身一定是可达的,这样从它们出发遍历到的对象才能保证一定可达。那么,Java 里有哪些对象是一定可达呢?主要有以下四种:

            虚拟机栈(帧栈中的本地变量表)中引用的对象。
            方法区中静态属性引用的对象。
            方法区中常量引用的对象。
            本地方法栈中 JNI 引用的对象。

    3、回收垃圾的方法有哪些?

     

      上面已经知道,所有 GC Roots 不可达的对象都称为垃圾,参考下图,黑色的表示垃圾,灰色表示存活对象,绿色表示空白空间。

      那么,我们如何来回收这些垃圾呢?

      标记-清理

      第一步,所谓“标记”就是利用可达性遍历堆内存,把“存活”对象和“垃圾”对象进行标记,得到的结果如上图;
      第二步,既然“垃圾”已经标记好了,那我们再遍历一遍,把所有“垃圾”对象所占的空间直接 清空 即可。

      结果如下:

      这便是 标记-清理 方案,简单方便 ,但是容易产生 内存碎片。

      标记-整理

      既然上面的方法会产生内存碎片,那好,我在清理的时候,把所有 存活 对象扎堆到同一个地方,让它们待在一起,这样就没有内存碎片了。

      结果如下:

      这两种方案适合 存活对象多,垃圾少 的情况,它只需要清理掉少量的垃圾,然后挪动下存活对象就可以了。

      复制

      这种方法比较粗暴,直接把堆内存分成两部分,一段时间内只允许在其中一块内存上进行分配,当这块内存被分配完后,则执行垃圾回收,把所有 存活 对象全部复制到另一块内存上,当前内存则直接全部清空。

      参考下图:

      起初时只使用上面部分的内存,直到内存使用完毕,才进行垃圾回收,把所有存活对象搬到下半部分,并把上半部分进行清空。

      这种做法不容易产生碎片,也简单粗暴;但是,它意味着你在一段时间内只能使用一部分的内存,超过这部分内存的话就意味着堆内存里频繁的 复制清空。

      这种方案适合 存活对象少,垃圾多 的情况,这样在复制时就不需要复制多少对象过去,多数垃圾直接被清空处理。

      

     4、什么是分代回收机制?

      (后记,先学习下...)

       

      

  • 相关阅读:
    我渴望自由和成功(愿与君共勉)
    gdb使用 和core dump文件调试
    谷歌浏览器快捷键大全
    Android适屏
    BestCoder Round #33
    NAT&amp;Port Forwarding&amp;Port Triggering
    程序员应该学习的书
    java代码调用rtx发送提醒消息
    js实现excel导出
    一个跨界程序员:不务正业的这几年,我如何让自己的收入翻了十倍(转)
  • 原文地址:https://www.cnblogs.com/zhengzeze/p/7680653.html
Copyright © 2011-2022 走看看