zoukankan      html  css  js  c++  java
  • Java的GC是什么?做了什么?

    Java GC是Java的垃圾回收机制

    • Java堆是被所有线程共享的一块内存区域,所有对象实例和数组都在堆上进行内存分配。为了高效的进行垃圾回收,虚拟机把堆内存分为新生代,老年代和永久代3个区域
    • 新生代可以分为Eden区和Survivor Space(S0,S1)区,大多数情况下,对象在Eden区分配,当Eden没有足够的内存空间时触发一次Minor GC
    • Survivor是幸存区,是新生代和老年代的缓冲区域,当新生代发生MinorGC时,会将存活的对象从Eden区移动到S0内存区域,并清空Eden区,当再次发生Minor GC时,将Eden和S0中存活的对象移到S1区;存活对象反复在S0和S1移动,当对象在Surivivor之间移动或者从Eden移动到Surivivor区时,对象的GC年龄会不断增加,当GC年龄超过默认阈值15会进入老年代
    • 老年代用于存放经过几次MinorGC后依然存活的对象,当老年代空间不足时会触发Full GC/Major GC,速度比MinorGC慢十多倍

    如何判断对象是否存活

    • 引用计数法

    对象上添加一个引用计数器,每当有一个对象引用它时,计数器加1,当使用完该计数器时,计数器减1,计数器为0表示该对象不被使用

    优点:实现简单,判定高效

    缺点:无法解决对象之间相互引用的问题

    • 可达分析法

    通过一系列的GC Roots对象作为起点,从这些起点开始向下搜索,搜索路径称为引用链

    可作为GC Roots的对象:

    1. 本地变量表中引用的对象 / 虚拟机栈中引用的对象
    2. 方法区中静态变量引用的对象
    3. 方法区中常量引用的对象
    4. Native方法引用的对象

    当一个对象到GCRoots没有任何引用链时,就表示该对象可以被回收

    使用可达性分析法判断一个对象是否可被回收需要经过两次标记:

    1. 对象ObjectA到GC Roots没有引用链,进行第一次标记
    2. 如果ObjectA重写了finalize方法,且还未执行过,那么ObjectA会被插入到一个F-Queue队列中,再由一个虚拟机自动创建的,低优先级的Finalizer线程触发其finalize方法。finalize方法中如果对象ObjectA与引用链中的对象建立联系,那么在进行第二次标记时ObjectA会被移出即将回收的集合(注:finalize方法只会被JVM调用一次)

    GC算法:

    • 标记清除(老年代)

    对待回收的对象进行标记

    缺点:标记和清除过程效率都很低,收集之后会留下很多内存碎片,不利于大对象的分配

    • 复制(年轻代)

    将内存分为大小相等的A和B两份,每次只使用一份,A中内存用完了,就把A中存活的对象复制到B中,并清空A的内存

    优点:只需要标记存活的对象,标记效率得到提高;避免了内存碎片的问题

    缺点:可用内存缩小为原来的一半

    • 标记整理(老年代)

    老年代中,对象的存活率较高,复制算法效率比较低,在标记整理算法中,标记出所有存活的对象并移到一端,然后直接清理边界以外的内存

  • 相关阅读:
    数组以字符串记录(字符串转数组)
    linux下OpenSSL的RSA密钥生成
    php rsa加密解密实例 及签名验证-自己实践
    php rsa加密解密实例
    PHP的openssl加密扩展使用小结
    支付宝开放平台 配置RSA(SHA1)密钥 OpenSSL配置公钥私钥对
    HTTP缓存控制
    java去任意范围的随机数
    (转)Eclipse4.2 Tomcat启动报错 A child container failed during start
    模态框事件介绍
  • 原文地址:https://www.cnblogs.com/qf123/p/8528147.html
Copyright © 2011-2022 走看看