zoukankan      html  css  js  c++  java
  • JVM垃圾回收机制二

    对象的回收

    垃圾的回收涉及的几个问题:何时回收,由谁回收,怎样回收。这几个问题我们一一来解决。

    1、何时回收----对象的生死判定

    对象达到什么条件才能判断这个对象已经无用了。常见的判断对象生死的方法有两种:
    (1)引用计数法
    给每个对象添加一个引用计数器,只要有地方引用到这个对象,这个对象的计数器就会加1,当引用失效时,计数器就相应的减1。
    引用计数法的问题:当两个对象互相引用,并且其他任何地方都没有引用这两个对象,那么根据引用计数法判定就永远无法回收这两个对象。
    (2)可达性分析
    通过一系列的成为GC Roots的对象作为起点,然后向下搜索,搜索的路径成为引用链,当一个对象到GC Roots没有任何引用链时,那么就说明次对象不可达。
    GCRoots对象包括:
    方法区:类静态属性引用的对象
    方法区:常量引用的对象
    虚拟机栈:局部变量表中存储的对象引用引用的对象
    本地方法栈:JNI方法引用的对象
    关于可达性分析和GC Roots有很多可说的,详细请点-------------------------------

    2、怎样回收----垃圾回收算法

    通过对象的生死判定算法我们已经知道那些对象已经死了,那我们怎样才能将这些对象回收呢?垃圾回收算法告诉我们这些无用的对象应该怎样回收。垃圾回收算法大体分为三种:复制算法,标记-清除算法,标记整理算法。其中复制算法常用于对新生代的收集,标记清除和标记整理用于对老年代的收集,具体的原因下文会介绍。
    (1)复制算法
    将可用的内存划分成大小相等的两块,每次只是用其中的一块,当这一块内存使用完了之后,就将还存活的对象复制到另一块内存上,然后把已经使用过的内存空间统一清理掉。

    该回收算法的效率虽高,但内存空间的使用效率并不高,因为总是有一般的内存时间使用不上。所以现在商用的JVM虚拟机一般不会将内存空间划分为两个相等的两块,而是划分成一个较大的Eden区和两块较小的Survivor区,Eden和Survivor的比例大小为8:1:1。具体的分代请看https://www.cnblogs.com/ozho/p/10589077.html
    (2)标记清除算法
    标记清除算法分为标记阶段和清除阶段。
    标记阶段:通过可达性分析将需要清除的对象标记
    清除阶段:将标记的对象清除。
    标记清除算法的问题:效率不高并且会产生大量不连续的内存碎片

    (3)标记整理算法
    是对标记清除优化的一种算法。在清除阶段之后,会将所有存活的对象移动到内存的一端,然后清理掉剩余可用的内存空间

    再谈分代收集
    上文已经提到新生代收集由复制算法实现,老年代由标记清除或者标记整理算法实现。新生代收集只能由复制算法实现,老年代只能由标记清除或者标记整理算法实现的原因:
    新生代中大多数对象都是“朝生夕死”的,每经过一次Minor GC都会有一大批对象死去,只有少量的对象存活。所以这些少量存活对象复制成本很低,但是在老年代中对象的存活率很高,如果采用Eden区:Suvivor=8:1的比例分配,没有足够的分配空间分配。
    永久代的垃圾回收;
    永久代的垃圾回收主要为两部分:无用的类和废弃的常量。
    关于“由谁回收”的问题下篇继续分析:垃圾回收器
    参考:《深入理解JVM虚拟机》

  • 相关阅读:
    JNI_Z_02_函数参数_JNIEnv*_jclass_jobject
    JNI_Z_01_获取Clazz
    文章网址
    nginx安装,反向代理配置
    排序的hashmap(guava)
    Unirest-拼装http请求发送rest接口
    mac远程连接windows
    java class遍历属性
    mongodb mongotemplate聚合
    java tar.gz文件生成
  • 原文地址:https://www.cnblogs.com/ozho/p/10595403.html
Copyright © 2011-2022 走看看