垃圾回收我们主要从以下三个方面进行描述

垃圾对象的判断

目前判断对象为垃圾对象有两种方法:引用计数法,可达性分析法,目前普遍是的是可达性分析法

可达性分析法的实现原理:

定义gcroot一直往下找,如果能找到对象,证明该对象在使用,如果找不到该对象,标记该对象应该回收。上图中栈作为gcroot只是其中一种情况,可作为gcroots的对象有虚拟机栈(栈帧中的局部变量表),方法区的类属性所引用的对象,方法区中常量所引用的对象,本地方法栈中引用的对象。

引用计数法的实现原理:

在对象中添加一个引用计数器,当有地方引用这个对象的时候引用计数器的值就+1,当引用失效的时候,计数器的值就-1,问题就是,如果a、b引用断开,这时候A、B对象计数器的值都是1,所以当循环引用的时候,不能进行垃圾回收。我们可通过代码试验此过程,注意我们需要配置以下虚拟机参数才可以看到垃圾回收日志:

垃圾回收算法

常见的垃圾回收算法有标记-清除算法,复制算法,标记-整理算法,分代收集算法。

标记清除算法:

此算法分为两个阶段,标记阶段(找到所有可访问的对象进行标记)和清除阶段(遍历堆把未被标记的对象清除)

此算法主要存在两方面的问题,效率问题和空间问题。这样会使不连续的空间越来越多,实在找不到空间的时候回触发再一次的垃圾回收。

标记整理算法

标记整理算法可以说是标记清除算法的升级版,标记整理算法也分为两个阶段,标记和整理,标记阶段是和标记清除算法的第一阶段一模一样的,均是遍历GC Roots,将存活的对象标记;在整理阶段会移动所有存活的对象,且按照内存地址次序依次排序,然后将末端内存地址以后的内存全部回收。

因为需要整理内存,与标记清除算法相比,标记整理算法需要花费更多的时间。

复制算法

复制算法将堆上的内存分为大小相等的两个区域,一个是活动区域,一个是空闲区域。在程序运行过程中使用活动区域,也就是有一半的空间被浪费掉

首先找出活动空间中所有存活的对象,将这些对象复制到空闲区域,将之前的活动空间清空,并变为空闲空间,存货对象所在的区域变为活动区域,这样就能保证在内存回收完毕后有一大片连续的可用空间。

分代回收算法

当前商用虚拟机基本都采用分代垃圾回收算法来回收垃圾,它主要是根据对象的生命周期将内存划分,然后进行分区管理

分代垃圾回收机制将堆空间分为新生代和老年代,新生代又被分为Eden区,From区,To区。当创建一个对象的时候,在Eden区进行操作,当Eden区内存不足的时候,会触发一次YoungGC(年轻代的垃圾回收),将存活的对象复制到From区,Eden区被清理,并继续创建新的对象,当内存再次不足的时候再次触发YoungGC,将Eden区与From区存活的对象复制到To区,下一次YoungGC的时候,将Eden区与To区中存活的对象复制到From区,经过若干次YoungGC后,还存活的对象会被复制到老年代。

垃圾收集器

serial收集器:最基础,发展最悠久的单线程垃圾收集器,适合桌面应用,适用于内存分配比较小,收集垃圾比较快的应用。

如有四个java线程在运行,垃圾收集时java线程停止,垃圾收集后,java线程继续进行。

parnew收集器:parnew收集器是是serial收集器的多线程版本,使用多线程进行垃圾收集(一般用于新生代收集器)

parallel Scavenge收集器:采用复制算法的多线程收集器,可达到可控制的吞吐量(cpu用于运行用户代码的时间与cpu消耗的总时间的比值(垃圾收集时间+用户代码执行时间)),可用-XX:MaxGCPauseMillis来设置,垃圾收集器的最大停顿时间,用-XX:GCTimeRatio来设置吞度量大小。此收集器与parnew比较相似,但是对吞度量要求比较高。

CMS收集器

CMS收集器是基于标记-清除算法实现的,其运作步骤为初始标记,并发标记,重新标记,并发清除(一般用作老年代收集器)

其中,初始标记,重新标记需要停止正在运行的java线程,初始标记是标记一下GCRoots能直接关联到的对象,速度很快,并发标记是GC Roots Tracing的过程(根据可达性分析法进行关联的过程),重新标记是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的对象的标记记录,这个阶段停顿的时间比初始标记稍长,但远比并发标记的时间短。可以看出,CMS收集器的耗时时间长的过程都可以与用户线程一起并发的执行。

G1收集器

G1收集器具有并行与并发结合,分代收集,空间整合,可预测的停顿等特点,采用标记整理算法,G1收集器不会产生空间碎片,分配大对象时不会因为无法找到连续空间而提前触发下一次GC,G1收集器能让使用者明确在一个长度为N毫秒的时间片段内,消耗在垃圾收集上的时间不能超过多少,上面提到的收集器收集的范围都是整个新生代或者老年代,而G1将java堆划分为多个大小相等的独立区域(Region),新生代和老年代不再是物理隔阂了。

jvm(四):垃圾回收的更多相关文章

  1. JVM(四) 垃圾回收

    1. 堆内存结构 Java堆从GC的角度可以细分为:新生代(Eden区.From Survivor区和To Survivor区)和老年代. 1.1 新生代 新生代是用来存放新生的对象.一般占据堆的1/ ...

  2. JVM的垃圾回收机制详解和调优

    JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都 ...

  3. jvm的垃圾回收算法

    一.对象存活判断判断对象是否存活一般有两种方式:1.引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收.此方法简单,无法解决对象相互循环引用的问题.2 ...

  4. JVM的垃圾回收机制 总结(垃圾收集、回收算法、垃圾回收器)

     相信和小编一样的程序猿们在日常工作或面试当中经常会遇到JVM的垃圾回收问题,有没有在夜深人静的时候详细捋一捋JVM垃圾回收机制中的知识点呢?没时间捋也没关系,因为小编接下来会给你捋一捋. 一. 技术 ...

  5. 扒一扒JVM的垃圾回收机制,下次面试你准备好了吗

      相信和小编一样的程序猿们在日常工作或面试当中经常会遇到JVM的垃圾回收问题,有没有在夜深人静的时候详细捋一捋JVM垃圾回收机制中的知识点呢?没时间捋也没关系,因为小编接下来会给你捋一捋. 一. 技 ...

  6. 2.1.JVM的垃圾回收机制,判断对象是否死亡

    因为热爱,所以坚持. 文章下方有本文参考电子书和视频的下载地址哦~ 这节我们主要讲垃圾收集的一些基本概念,先了解垃圾收集是什么.然后触发条件是什么.最后虚拟机如何判断对象是否死亡. 一.前言   我们 ...

  7. JVM中垃圾回收机制如何判断是否死亡?详解引用计数法和可达性分析 !

    因为热爱,所以坚持. 文章下方有本文参考电子书和视频的下载地址哦~ 这节我们主要讲垃圾收集的一些基本概念,先了解垃圾收集是什么.然后触发条件是什么.最后虚拟机如何判断对象是否死亡. 一.前言   我们 ...

  8. 03 JVM的垃圾回收机制

    1.前言 理解JVM的垃圾回收机制(简称GC)有什么好处呢?作为一名软件开发者,满足自己的好奇心将是一个很好的理由,不过更重要的是,理解GC工作机制可以帮助你写出更好的Java程序. 在学习GC前,你 ...

  9. jvm详情——3、JVM基本垃圾回收算法回收策略

    JVM基本垃圾回收算法回收策略 引用计数(Reference Counting):比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的 ...

  10. JVM的垃圾回收机制

    JVM的垃圾回收机制:(GC通过确定对象是否被活动对象引用来确定是否收集该对象.) 1.触发GC(Garbage Collector)的条件. (1.GC在优先级最低的线程中运行,在未运行的线程中进行 ...

随机推荐

  1. api-gateway实践(09)支持rest服务注册

    一.GET-GET 1.前端定义 2.后端定义 2.1.基础定义 2.2.path参数.head参数.query参数 2.3.常量参数 2.4.系统参数 2.5.结果定义 二.POST-POST 1. ...

  2. maven常见问题处理(3-1)修改maven 默认使用的 jdk 版本

    Eclipse工程应设定了1.8,maven编译仍然使用1.6的解决办法 解决方式有两种,一种是配置 pom.xml,一种是配置 settings.xml. 方式一:settings.xml 配置 打 ...

  3. 丢掉DDL,我用这招3分钟清空 MySQL 9亿记录数据表

    摘要:最近由于福建开机广告生产环境的广告日志备份表主键(int类型)达到上限(21亿多),不能再写入数据,需要重新清空下该表并将主键重置,但由于表里有8亿多记录的数据量,使用重置命令及DDL命令执行地 ...

  4. spring boot定制Jackson ObjectMapper,为什么不生效

    先说结论: 项目中定制了spring 的redisTemplate,而这个template没有使用我自定义的Jackson ObjectMapper.所以不生效. 下面是详细过程: 起因是spring ...

  5. 记录下项目中常用到的JavaScript/JQuery代码一(大量实例)

    一直没有系统学习Javascript和Jquery,每次都是用到的时候去搜索引擎查,感觉效率挺低的.这边把我项目中用的的记录下,想到哪写哪,有时间再仔细整理. 当然,由于我主要是写后端java开发,而 ...

  6. transform-style为什么子元素需要定位?

    有个园友问我一个问题: 为什么ul和li都要absolute定位呢,让其自然排列,然后沿着x轴进行旋转不行吗?这块一直无法理解. 在这里进行详细的解答: 我们知道圆是有圆心和半径的, 我用定位的方式就 ...

  7. Docker:云栖社区开源论题及Spark开源论题

    https://yq.aliyun.com/topic/78?spm=5176.8290451.656547.7.rMYhAF https://yq.aliyun.com/activity/155?u ...

  8. Centos下安装 .net Core运行程序

    首先要进行更新下镜像文件 sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo sh -c 'echo -e ...

  9. 小工具:批量导入导出主机上的docker镜像

    工作需要,将主机上的部分镜像导出为tar文件,放便在其他主机上使用 用python实现了一个批量打包脚本: import re import os import subprocess if __nam ...

  10. [LeetCode] Replace Words 替换单词

    In English, we have a concept called root, which can be followed by some other words to form another ...