第三章垃圾收集器与内存分配策略

3.2对象死亡的判断方法

3.2.1引用计数法

给对象添加一个引用计数器,每当一个地方引用它就+1,引用失效就-1,当计数器为0时就表示对象已经死亡。

缺点是无法解决循环引用问题

3.2.2可达性分析

将GC root作为根节点向下遍历,无法遍历到的对象(GC Root到这个对象不可达)就表示该对象已经死亡。

3.2.3对象的自救

已经死亡的对象会被第一次标记,然后进行筛选,筛选出是否有必要执行finalize()方法,如果对象有并且是第一次被调用那么对像将被放在F-Queue队列中,等待虚拟机触发这个方法,如果在finalize()方法中与任何一个对象建立关联则该对象还可以存活

3.2.4回收方法区

永久代的回收(full GCf)主要内容是:废弃常量和无用的类

常量的回收:和堆中的对象相似,当系统中没有String对象引用时会被回收。

无用的类必须满足三个条件:

    该类的所有实列已经被回收
    1. 加载该类的classloader已经被回收
    2. 该类对应的java.lang.Class对象没有被任何地方引用,无法通过反射访问该类

3.3垃圾回收算法

3.3.1标记-清楚算法

先将所有可回收对像进行标记然后再回收
缺点是效率低,产生的碎片多

3.3.2复制算法

将存活的对象复制到另一半内存中,当另一半内存不够时会向永久代进行分配担保
将堆分为了Eden From Survivor, To Survivor 默认比列是8:1:1

3.3.3分代收集算法

新生代使用复制算法   老年代使用标记清理或标记整理

3.4垃圾收集器

Serial:  最基本最悠久的,单线程,工作时会stop the world  简单而高效
ParNew: Serial的多线程版本
Parallel Scavenge:可以控制吞吐量,和最大垃圾收集停顿时间。动态调节新生代的大小,Eden与Survivor的比列,晋升老年代对象的大小等细节参数提供最合适的停顿时间或者最大吞吐量
Serial Old:serial的老年代版本
Parallel Old:Parallel的老年代版本
CMS: 工作分为四个步骤     初始标记 并发标记   重新标记  并发清除
         CMS收集器对CPU资源敏感
          CMS收集器无法处理浮动的垃圾
           CMS会产生很多碎片
G1:是目前的最新成果,它并行与并发   分代收集   空间整合  可预测的提顿      将java堆分为多个Region
        工作步骤:初始标记,并发标记 最终标记  筛选回收

3.5内存分配与回收策略

  1. 对象优先在Eden分配
  2. 大对象直接进入老年代
  3. 长期存活的对象进入老年代也就是对象的年龄>=MaxTenuringThreshold设定的年龄
  4. 动态对象年龄:满足同年对象达到Survivor空间的一半

原文地址:https://www.cnblogs.com/c-lover/p/10034460.html

时间: 2024-10-08 15:37:59

第三章垃圾收集器与内存分配策略的相关文章

第三章 垃圾收集器和内存分配策略

第三章 垃圾收集器和内存分配策略 对象已死吗 引用计算方法 可达性分析算法 通过一些列的GC roots 对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象到GC roots 没有任何引用链的则证明对象不可用的 虚拟机栈中的引用的对象 方法区中类静态属性引用的对象 方法去区中常量引用的对象 本地方法栈中JNI引用的对象 生存还是死亡 一次筛选,筛选是否有必要执行 finalize()方法 没有覆盖或者finalize()已经被调用过  视为没必要执行 放入一个F-Qu

第三章 垃圾收集器与内存分配策略

书中笔记: 也许并不会死: 要宣告回收一个对象死亡,至少要经历两次标记过程: 当可达性分析发现一个对象不可达的时候,将标记第一次并进行筛选,筛选的条件是此对象是否有必要执行finalize()方法,当对象没有覆盖finalize或者已被调用过,则虚拟机认为此对象没必要执行finalize,  如果判断有必要执行,则此对象将会被放入一个F-Queue队列中,之后会被一个优先级比较低的Finalizer线程去调用,但是并不会等待他执行完毕,因为此对象的finalize并不可靠,可能会死循环之类的,如

《深入理解JAVA虚拟机》----------第三章 垃圾收集器与内存分配策略,读后感(中)

1.垃圾收集器 1.1 Serial收集器 这个收集器是一个单线程的收集器,它在进行垃圾收集时,必须暂停其他所有的工作线程. 它是虚拟机运行在Client模式下的默认新生代收集器,它简单而高效. 1.2 ParNew收集器 其实就是Serial收集器的多线程版本,目前只有它能与CMS收集器配合工作. 原文地址:https://www.cnblogs.com/technologykai/p/10622586.html

[深入理解JVM虚拟机]第3章-垃圾收集器、内存分配策略

垃圾收集器 判断对象是否需存活 回收堆 判断对象是否存活: 方法一:引用计数法.对象被引用一次就+1,当为0时回收对象.缺点:无法解决循环引用问题. 方法二:可达性分析算法.记录当前对象是否有和GC Roots中对象的引用链.(其中,可以作为GCRoots对象的有:虚拟机栈中引用的对象.方法去中类静态属性引用的对象.方法区中常量引用的对象.本地方法栈中引用的对象.) 不可达对象并不是一定被垃圾收集的,当这个对象有必要执行finalize()并finalize里自己和某个对象建立关联,即可在第二次

垃圾收集器与内存分配策略(三)之HotSpot的算法实现

垃圾收集器与内存分配策略(三)--HotSpot的算法实现 Java JVM 垃圾回收 在HotSpot虚拟机上实现这些算法时,必须对算法的执行效率有着严格的考量,才能保证虚拟机高效地运行. 1. 枚举根节点 采用可达性分析从GC Roots节点中找引用链为例 存在的缺点: 1.在前面找出还存活对象时,采用可达性分析从GC Roots节点中找引用链时,可作为GC Roots的节点主要在全局性的引用(方法区的常量或类静态属性引用)与执行上下文(虚拟机栈栈帧中的本地变量表或本地方法栈中的Native

Java虚拟机垃圾收集器与内存分配策略

Java虚拟机垃圾收集器与内存分配策略 概述 那些内存需要回收,什么时候回收,如何回收是GC需要完成的3件事情. 程序计数器,虚拟机栈与本地方法栈这三个区域都是线程私有的,内存的分配与回收都具有确定性,内存随着方法结束或者线程结束就回收了. java堆与方法区在运行期才知道创建那些对象,这部分内存分配是动态的,本章笔记中分配与回收的内存指的就是:java堆与方法区. 判断对象已经死了 引用计数算法:给对象添加一个引用计数器,每当有一个地方引用它,计数器+1;引用失败,计数器-1.计数器为0则改判

垃圾收集器以及内存分配策略

垃圾回收 垃圾回收的三个问题: 哪些内存需要回收? 什么时候回收? 如何回收? 1.哪些对象需要回收? 判断对象是否存活的办法: 引用计数算法:给对象中添加一个引用计数器,有一个地方引用就+1,引用失效就-1.只要计数器为0则对象已死. 优点:简单易实现: 缺点:无法解决对象之间相互引用的问题.(JVM也因为此种原因没有使用它) 根搜索算法: 通过选取出一个GC Roots对象,已它作为起始点,如果对象不可达,则对象已死. GC Roots对象: 虚拟机栈中引用的对象 方法区中类静态属性引用的对

深入理解java虚拟机----->垃圾收集器与内存分配策略(下)

1.  前言 内存分配与回收策略 JVM堆的结构分析(新生代.老年代.永久代) 对象优先在Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保  2.  垃圾收集器与内存分配策略 Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决两个问题: 给对象分配内存; 回收分配给对象的内存. 对象的内存分配,往大方向上讲就是在堆上的分配,对象主要分配在新生代的Eden区上.少数也可能分配在老年代,取决于哪一种垃圾收集器组合,还有虚拟机中的相关内存的参

垃圾收集器与内存分配策略(二)

垃圾收集算法简介 1.标记-清除算法       标记-清除算法主要分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一进行回收.对象的标记过程在垃圾收集器与内存分配策略(一)中已经介绍过. 存在的问题:一是效率问题,标记和清除的效率都不高:二是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时无法找到足够的内存而不得不提前触发另一次垃圾收集动作. 2.复制算法       复制算法:它将内存按照容量划分为大小