深入理解java虚拟机之——JVM垃圾回收策略

  • 如何判断一个对象是否存活

    引用计数算法:给对象中添加一个引用计数器,每当有引用它时,计数器值就加1;当引用

  失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用。

      Java虚拟机里面没有选用引用计数算法来管理内存,其中主要原因是他很难解决对象

    之间相互引用的问题。

    例如:对象objA和objB都有字段instance字段,切互相赋值,但实际上这两个对象已经不可

  能被访问了,但因为他们互相引用着对方,导致他们的引用计数都不为0,于是导致他们无法回收。

  (Java中这种情况是可以回收的)

public class ReferenceGC {

    public Object instance = null;

    public static void testGC(){
        ReferenceGC objA = new ReferenceGC();
        ReferenceGC objB = new ReferenceGC();
        objA.instance = objB;
        objB.instance = objA;

        objA = null;
        objB = null;
    }
}

     可达性分析算法:通过一系列的称为"GC Root"的对象作为起点,从这些节点开始向下搜索,

  搜素所走过的路径称为引用链(Reference Chain),当一个对象到GC Root没有任何的引用链

  相连,就判定对象可以被回收。Java, C#等语言都是使用这种算法判读对象的存活的。

    GC Root的对象包括下面几种:

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

      方法区中类静态属性引用的对象

      方法区中常量引用的对象

      本地方法栈中JNI(Native方法)引用的变量

  • 引用

    Java1.2后对引用进行扩充,分为:

      强引用:类似 Object obj = new Object()这类引用,垃圾收集器永远不会进行回收

      软引用:用来描述一些还有用但非必须的对象。系统在内存溢出异常之前,将会把这些

    对象列入回收范围之中进行。二次回收。如果这次回收还没有足够的内存,才会抛出内存异常。

    SoftReference类实现。

      弱引用:比软引用更弱一些,也是用来描述非必须对象。回收发生在下次垃圾收集器回收时。

    WeakReference类实现。

      虚引用:最弱一种引用,虚引用无法影响对象其生存时间,也无法通过虚引用获得

    对象,唯一目的就是对象被垃圾收集器回收时,收到一个系统通知。PhantomReference类实现。

  • 对象生存还是死亡

    如果对象在进行可达性分析后发现没有与GC Roots相连的引用链,那么它将会被第一次标记并且进行

  一次筛选,筛选条件是该对象是否覆盖finalize()方法,是否执行过finalize()方法。如果为覆盖或执行过则

  对象死亡。

    如果覆盖finalize()且有必要执行finalize(),则对象放入F-Queue的队列中,之后由虚拟机自动建立,

  低优先级的Finalizer线程去执行。这里的执行是指虚拟机会触发这个方法,但不承诺会等待它运行结束。

  (该方法不建议使用)

  • 方法区回收

    方法区主要回收:废弃常量和无用的类 

    废弃常量:例如一个字符串"abc"已经进入常量池中,但是当前系统没有其他地方引用这个字面量。

    无用的类:

      该类的所有实例都已经被回收,也就是Java堆中不存在该类的任何实例

      加载该类的ClassLoader已经被回收

      该类对应的Java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的

    方法。

  • 垃圾收集算法

    标记-清除算法:首先标记出所有需要回收的对象,在标记完成后统一回收所有标记的对象,标记过

  程在上面提过。

    不足:1.效率问题,标记和清除两个过程效率不高

       2.空间问题,标记清楚产生大量内存碎片

    复制算法:将内存安装容量分为大小相等的两块,每次使用其中一块。当回收时,将存活的对象复制到

  为使用的内存中,清楚已使用过的内存。

    不足:内存缩小到运来的一半

    Java在新生代中采用这种算法,不过是将内存分为Eden和两块Survivor,每次使用Eden和其中的Suvivor

  当回收时,将Eden和Suvivor存活的内存复制到未使用的Suvivor空间。HotSpot默认Eden与Suvivor比例为

  8:1,相当于可以使用90%的内存,如果存活的内存超过Suvivor空间,就是用老年代进行分配担保。

    标记-整理算法:过程与标记-清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活

  的对象向一端移动,然后清理掉端边界以外的内存。

    分代收集算法:将内存划分成几块,各个区域采用最适当的收集算法。Java一般把Java堆分为新生代和老年代,

  按各个年代特点采用适当的算法。

  垃圾收集器:

    新生代:Serial收集器,ParNew收集器,Parallel Scavenge收集器

    老年代:CMS, Seral Old(MSC), Parallel Old收集器

    (GI收集器具体不了解)

  

时间: 2024-11-13 04:07:19

深入理解java虚拟机之——JVM垃圾回收策略的相关文章

深入理解Java虚拟机(jvm性能调优+内存模型+虚拟机原理)视频教程

14套java精品高级架构课,缓存架构,深入Jvm虚拟机,全文检索Elasticsearch,Dubbo分布式Restful 服务,并发原理编程,SpringBoot,SpringCloud,RocketMQ中间件,Mysql分布式集群,服务架构,运 维架构视频教程 14套精品课程介绍: 1.14套精 品是最新整理的课程,都是当下最火的技术,最火的课程,也是全网课程的精品: 2.14套资 源包含:全套完整高清视频.完整源码.配套文档: 3.知识也 是需要投资的,有投入才会有产出(保证投入产出比是

深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)PDF下载

网盘下载地址:深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)PDF下载 – 易分享电子书PDF资源网 作者: 周志明 出版社: 机械工业出版社 副标题: JVM高级特性与最佳实践 出版年: 2013-9-1 页数: 433 定价: 79.00元 装帧: 平装 内容简介 · · · · · · <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)>内容简介:第1版两年内印刷近10次,4家网上书店的评论近4?000条,98%以上的评论全部为5星级的好评,是整个Java图书领域公

深入理解JAVA虚拟机之JVM性能篇---垃圾回收

一.基本垃圾回收算法 1. 按基本回收策略分 1) 引用计数(Reference Counting)  对象增加一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 2)标记-清除(Mark-Sweep)  执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除. 缺点是此算法需要暂停整个应用,同时会产生内存碎片. 3)复制(Copying) 把内存空间划为两个相等的区域,每

Java虚拟机四:垃圾回收算法与垃圾收集器

在Java运行时的几个数据区域中,程序计数器,虚拟机栈,本地方法栈3个区域随着线程而生,随线程而灭,因此这几个区域的内存分配和回收具有确定性,不需要过多考虑垃圾回收问题,因为方法结束或者线程结束时,内存就回收了.但是方法区和堆区不一样,一个接口或者实现类所需要的内存可能不一样,一个方法的多个分支需要的内存也可能不一样,只有程序运行时才能知道创建哪些对象,这部分内存的分配和回收是动态的. 在进行垃圾回收时候,首先需要判断哪些对象需要回收,这就涉及到回收算法的问题. 一.垃圾回收算法 1.标记-清除

《深入理解Java虚拟机:JVM高级属性与最佳实践》读书笔记(更新中)

第一章:走进Java 概述 Java技术体系 Java发展史 Java虚拟机发展史 1996年 JDK1.0,出现Sun Classic VM HotSpot VM, 它是 Sun JDK 和 OpenJDK 中所带的虚拟机,最初并不是Sun开发 Sun Mobile- Embedded VM/ Meta- Circular VM BEA JRockit/ IBM J9 VM JRockit曾号称世界上最快的java虚拟机,BEA公司发布.J9属于IBM主要扶持的虚拟机 Azul VM/ BEA

深入理解Java虚拟机:JVM高级特性与最佳实践(一):java 内存区域与内存异常

如需转载,请标明转自何处 运行时数据区域: java 虚拟机在执行java程序的过程中会把他管理的内存化为若干个不同的数据区域.这些区域都有各自的用途,销毁与创建的时间,有的区域随着进程的启动而存在,有的则依赖用户的线程的启动和结束而创建和销毁,java虚拟机管理的内存分为一下几个数据区域: 1.程序计数器:当前线程所执行的字节码的行号指示器,通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支.循环.跳转.异常处理线程恢复都依赖与它. java 虚拟机的多线程是通过线程的轮流切换并分配

深入理解JAVA虚拟机之JVM性能篇---基础知识点

一.堆与栈 堆和栈是程序运行的关键,其间的关系有必要理清楚,两者如下图所示: 1. 堆: 所有线程共享,堆中只负责存储对象信息. 2. 栈: 在Java中每个线程都会有一个相应的线程栈与之对应(因为不同的线程执行逻辑有所不同,因此需要一个独立的线程栈),栈是运行单位,因此里面存储的信息都是跟当前线程(或程序)相关的信息,包括局部变量.程序运行状态.方法返回值等; 3. 总结: 栈是运行时的单位,而堆是存储的单位. 二.JAVA对象的大小 在Java中,一个空Object对象的大小是8byte,这

《深入理解Java虚拟机》- JVM如何进行异常处理

一.Java异常 在程序中,错误可能产生于程序员没有预料到的各种情况,或者超出程序员可控范围的环境,例如用户的坏数据.试图打开一个不存在的文件等.为了能够及时有效地处理程序中的运行错误,Java 专门引入了异常类. 二.Java常见异常分类 三.为什么产生异常 在 Java 中一个异常的产生,主要有如下三种原因: Java 内部错误发生异常,Java 虚拟机产生的异常. 编写的程序代码中的错误所产生的异常,例如空指针异常.数组越界异常等.这种异常称为未检査的异常,一般需要在某些类中集中处理这些异

《深入理解Java虚拟机:JVM高级特性与最佳实践》读书笔记

第一部分 走进Java 一.走进Java 1.概述 java广泛应用于嵌入式系统.移动终端.企业服务器.大型机等各种场合,摆脱了硬件平台的束缚,实现了"一次编写,到处运行"的理想 2.java技术体系结构 按照功能来划分 包括以下几个组成部分:Java程序设计语言,各种硬件平台的java虚拟机,Java API类库,来自商业机构和开源社区的第三方Java类库,Class文件格式 Java程序设计语言,java虚拟机,Java API类库统称为JDK,是用于支持java程序开发的最小环境