JAVA-虚拟机(2)-GC算法&回收器

垃圾回收主要内容:

  1. 那些内存需要回收?

  2. 什么时候回收?

  3. 如何回收?

垃圾回收主要针对运行时数据区那些区域?

  运行时数据区的线程私有区域有:虚拟机栈,本地方法栈,程序计数器等;

                 栈中的栈帧随着方法的进入和退出执行入栈和出栈,每个栈帧的内存分配在编译期就已经确定;

                 随着线程或方法的结束,内存也随着回收;

  运行时数据区的线程共享区域有:方法区,堆;

                 方法区和堆只有程序处于运行期才能确定创建那些对象,因此这部分内存分配和回收都是动态的;

                 垃圾回收的重点区域;

一,对象存活判断

  1,引用计数算法

    给对象添加一个引用计数器,被引用时计数器值+1,引用失效计数器值-1,当计数器值为0时对象不可能再被使用;

    主流Java虚拟机未选用该算法管理内存(未解决对象之间相互循环引用的问题)

    实现简单,判断效率高(应用:FlashPlayer,Python等)

  2,可达性分析算法

    将"GC Roots"对象作为起始节点,向下搜索,搜索走过的路径为引用链;当一个对象到GC Roots没有引用链时,则该对象是不可用的;

    可作为"GC Roots"的对象:

    【1】,方法区中静态属性引用的对象

    【2】,方法区中常量引用的对象

    【3】,虚拟机栈引用的对象 (栈帧中本地变量表)

    【4】,本地方法栈中JNI引用的对象 (Native方法)

二,垃圾回收算法

  1,标记-清除算法

     定义:先标记要回收的对象,然后统一回收;

     适用:存活对象较多的垃圾回收

     缺点:

      【1】,效率低; 标记和清除的过程效率不高;

      【2】,空间问题; 标记清除后产生大量不连续的内存碎片,给大对象分配内存时没有足够连续的内存空间,导致提前出发垃圾回收动作。

      

  2,复制算法

    定义:将可用内存划分成相等大小两块,每次只使用其中一块,当这一块用完后将还存活的对象复制到另一块,

       然后将已使用过的内存一次清理。

    适用:存活对象较少的垃圾回收

    优点:每次对整个半区进行内存回收,不用考虑内存碎片问题,只要移动堆顶指针,按顺序分配内存即可;

         实现简单,运行高效

    缺点:将内存缩小了一半

    其他:

      将新生代内存按照8:1:1分为Eden,From Survivor,To Survivor三个空间,每次使用Eden和From Survivor两个空间给对象分配内存,

      当内存不足垃圾回收时,将存活对象复制到To Survivor空间,然后清理Eden和From Survivor空间;这样相当于内存指浪费了10%;

      如果10%的To Survivor空间不够存放存活对象时需要老年代进行分配担保(将存活对象通过分配担保机制直接进入老年代)

  3,标记-整理算法

    定义:先标记要回收的对象,将存活对象移至一端,最后清理端边界以外的内存

      

  4,分代收集算法

    定义:根据对象存活周期将内存划分为新生代和老年代,然后根据每个年代的特点使用合适的回收算法;

       如:新生代存活对象少可以采用复制算法; 老年代存活对象多并且没有分配担保必须使用标记清理或标记整理回收算法

三,垃圾回收器

  1,

 

  

时间: 2024-10-07 22:12:43

JAVA-虚拟机(2)-GC算法&回收器的相关文章

Java虚拟机:GC算法深度解析

版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 在前面的文章里介绍了可达性分析算法,它为我们解决了判定哪些对象可以回收的问题,接下来就该我们的垃圾收集算法出场了.不同的垃圾收集算法有各自不同的优缺点,在JVM实现中,往往不是采用单一的一种算法进行回收,而是采用几种不同的算法组合使用,来达到最好的收集效果.接下来详细介绍几种垃圾收集算法的思想及发展过程.  最基础的收集算法 -- 标记/清除算法        之所以说标记/清除算法是几种GC算法中最基础的算法,是因为后续的收集算法都

Java虚拟机(4)-GC概述,如何回收对象

1.垃圾回收概述 随着程序的不断运行,程序所产生的对象必将越来越多,而系统的内存则是有限的,所以,将没有用的对象进行清除是程序长期稳定运行的关键. 垃圾回收主要关注三个问题 什么对象应该被回收? 当然是没有用的对象.当对象不再被引用时,我们认为该对象应该被回收.如何判断对象是否还被引用,会在后面详述. 对象应该在什么时间被回收? 程序在运行过程中,对象的引用关系是一直变化的,如何选择合适的时机开始GC,也是一个重要的问题,后面详述. 应该怎样回收? 当我们知道是无用对象后,如何将无用对象清除,保

java虚拟机之GC(转)

垃圾回收主要内容: 1. 那些内存需要回收? 2. 什么时候回收? 3. 如何回收? 垃圾回收主要针对运行时数据区那些区域? 运行时数据区的线程私有区域有:虚拟机栈,本地方法栈,程序计数器等: 栈中的栈帧随着方法的进入和退出执行入栈和出栈,每个栈帧的内存分配在编译期就已经确定: 随着线程或方法的结束,内存也随着回收: 运行时数据区的线程共享区域有:方法区,堆: 方法区和堆只有程序处于运行期才能确定创建那些对象,因此这部分内存分配和回收都是动态的: 垃圾回收的重点区域: 一,对象存活判断 1,引用

JAVA虚拟机垃圾回收算法原理

除了释放不再被引用的对象外,垃圾收集器还要处理堆碎块.新的对象分配了空间,不再被引用的对象被释放,所以堆内存的空闲位置介于活动的对象之间.请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的总空闲空间是足够的.这是因为,堆中没有连续的空闲空间放得下新的对象. 垃圾收集器算法 任何垃圾回收算法都必须做两件事,首先,它必须检测出垃圾对象.其次,它必须回收垃圾对象所使用的堆空间并还给程序.从根对象开始,任何可以被触及的对象都被认为是“活动的”对象(如果正在运行的程序可以访问到根对象和某个对象之间

Java虚拟机垃圾回收算法

1.标记清除算法:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象.缺点是效率问题和产生大量不连续的内存碎片,导致程序后期需要分配大对象时无法找到足够的连续内存而不得不提前出发另一次垃圾收集动作. 2.复制算法:将可用内存划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活着的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉. 3.标记整理算法:让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存. 当前商业虚拟机的垃圾收集都采用分代

Java虚拟机学习 - 垃圾收集算法(3)

跟踪收集器 跟踪收集器采用的为集中式的管理方式,全局记录对象之间的引用状态,执行时从一些列GC  Roots的对象做为起点,从这些节点向下开始进行搜索所有的引用链,当一个对象到GC  Roots 没有任         何引用链时,则证明此对象是不可用的. 下图中,对象Object6.Object7.Object8虽然互相引用,但他们的GC Roots是不可到达的,所以它们将会被判定为是可回收的对象. 可作为GC Roots 的对象包括: 虚拟机栈(栈帧中的本地变量表)中的引用对象. 方法区中的

深入理解Java虚拟机笔记---垃圾收集算法

当对象判定为"已死"状态,虚拟就要采取一定的手段将这些对象从内存中移除,即回收垃圾,回收过程有采用一定的算法.如下是一些主要的垃圾收集算法: 1.标记-清除算法 该算法是最基础的算法,分为"标记"和"清除"两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象.之所有说它是最基础的算法是因为后续的收集算法都是基于这种思路并对其缺点进行改进得到的.它的缺点主要有两个:一个是效率问题,标记和清除过程效率都不高:另外一个是空间问

java虚拟机(十一)--GC日志分析

打印日志相关参数: -XX:+PrintGCDetails -XX:PrintGCTimestamps -XX:PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log -XX:+PrintHeapAtGC -XX:+PrintTenuringDistriution:发生GC的时候,把Young区中对象的年龄打印出来 其余的参数应该能直接看懂的,就不解释了. Parallel日志: 默认情况下,都是使用Parallel收集器 JAVA_OPTS="

java虚拟机优化--gc日志

加入 wrapper.java.additional.5=-XX:+PrintGC wrapper.java.additional.6=-XX:+PrintGCDetails #wrapper.java.additional.7=-XX:+PrintGC:PrintGCTimeStamps wrapper.java.additional.7=-Xloggc:gc.log wrapper.java.additional.8=-XX:+PrintGCApplicationStoppedTime wr