最近又重新在读深入理解java虚拟机一书,吸取第一次读完到现在已经忘记的差不都的教训,这次的学习之旅想通过博客的形式记录下自己的所学所感,以备后续继续学习备忘所用!这次先记录下垃圾收集相关知识点:

垃圾收集一般有三件事情要做,一是哪些内存需要回收,二是什么时候回收,三是怎么去回收?

先来确定第一件事,也就是如何来确定需要回收的内存?主要有以下两种实现:

一、引用计数法

具体实现:每个对象内部维护一个引用计数器,对象每被引用一次则计数器加一,反之则减一,当引用计数器的值为0的时候则表示该对象不可能再被使用了;

优点:效率高;尽管维护计数器有一定的内存开销,但原理简单

缺点:不做特殊处理的话,循环依赖的对象无法被回收;这也好理解,比方说创建A,B两个对象,然后将A对象里的属性赋值给B,B在赋值给A(此时A,B两个对象的引用计数器的值至少为1),再将A,B对象均置空,按道理对象都置空了应该是属于可被回收的了,但是由于前面的引用还在计数器的值还是大于0的,按照引用计数法的逻辑是不应该被回收的

二、可达性分析

具体实现:维护一堆叫GC Roots的起始节点集合,从这些节点开始根据引用关系向下搜索,搜索过程所走过的路径称为引用链,如果某个对象到GC Roots没有任何引用链连接,则证明其不可能再被使用

优点:可以回收那些实际已不可能使用,但存在相互依赖的对象

缺点:不做优化GC Roots有可能过度庞大,导致判断效率降低

那些固定可作为GC Roots的对象:

虚拟机栈(栈帧中的本地变量表)中引用的对象,如各线程被调用的方法堆栈中使用到的参数,局部变量,临时变量等

方法区中类静态属性引用的对象,如java类的引用类型静态变量

方法区中常量引用的对象,如字符串常量池中的引用

本地方法栈中JNI(Native方法)引用的对象

虚拟机内部的引用,如基本数据类型对应的class对象,常驻的异常对象,系统类加载器

所有被同步锁(synchronized修饰)持有的对象

反应java虚拟机内部情况的JMXBean,JVMTI中注册的回调,本地代码换成等

然后确定第二件事情,什么时候进行回收?

需要注意的事,即使当某一对象到GC Roots已不可达,但是在GC之前还是会调用一次对象的finalize方法,如果finalize方法没有成功自救,则对象基本就会被回收了;

最后确定第三季事,怎么去回收?

常用的垃圾回收算法有以下几种:

一、标记-清除

将所有已被认定需要回收的对象打上标记,然后统一清除,或者反过来,标记那些存活的对象,清除没打标记的对象内存;这种做法简单粗暴且高效,但是由于回收的对象分布在堆中的各处,所以回收后会造成内存空间的不连续,这样不利于后期分配需要占大内存的对象

二、标记-复制(常用于新生代)

基于标记清除算法,针对其可能造成的内存空间不完整进行优化,具体做法是将内存分成两等块,一块正常分配对象,另一块用于垃圾收集后存放存活的对象,当一块对象分配满了需要GC时将所有存活的对象复制到一边,只回收另一边的内存,从而解决了回收后内存不规整的问题,但是考虑到复制成本,效率肯定会低于标记清除,并且将内存分成两块,明显浪费了内存空间,需要额外空间来做担保(老年代),以防止GC时对象全部存活的极端情况

三、标记-整理(常用语老年代)

同样基于标记清楚算法,前期的标记过程也一致,但是为了解决标记清除造成的空间不连贯以及标记复制可能造成的效率低下问题,标记整理算法在打完标记后,不是直接对对象进行清理,而是让所有存活的对象像某一端移动,然后直接清理掉边界以外的内存;通常在老年代使用

四、分代收集算法

根据对象存活周期的不同将对象分成几块,针对每块进行回收,基于以下三种假说:

分代假说

1,弱分代假说

大部分对象都是朝生夕灭的

2,强分代假说

熬过越多次垃圾收集的对象越难被回收

3,跨代引用假说

跨代引用的对象相比同代引用属于极少数

jvm之垃圾收集一之垃圾回收算法的更多相关文章

  1. Jvm垃圾收集器和垃圾回收算法

    概述: 目前内存的动态分配和内存的回收技术已经相当成熟,一切看起来都已经进入了“自动化”时代,为什么还要去了解GC和内存分配呢?原因很简单:当需要排查各种内存泄漏.内存溢出问题时,当垃圾收集器成为系统 ...

  2. jvm学习笔记一(垃圾回收算法)

    一:垃圾回收机制的原因 java中,当没有对象引用指向原先分配给某个对象的内存时候,该内存就成为了垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息 ...

  3. JVM虚拟机学习一:垃圾回收算法总结

    1.java虚拟机中涉及到的数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型. 基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某 ...

  4. java虚拟机学习-JVM调优总结-基本垃圾回收算法(7)

    可以从不同的的角度去划分垃圾回收算法: 1.按照基本回收策略分 引用计数(Reference Counting): 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计 ...

  5. 深入了解java虚拟机(JVM) 第六章 垃圾回收算法

    一.标记清除算法 标记清除算法顾名思义,就是将需要回收的对象进行标记,然后进行清除.那么这个算法就有标记和清除两种过程.标记过程主要是通过可达性分析算法进行判断存活对象,然后遍历所有的对象来找到需要回 ...

  6. JVM G1垃圾回收算法简要介绍

    JVM G1垃圾回收算法简要介绍 G1的特点 能够像CMS垃圾回收算法一样并发操作应用线程(潜台词:多核) 无需太长时间即可压缩空闲内存空间(潜台词:不会引起太多的GC停顿时间) 尽可能地让GC时长可 ...

  7. 6.GC垃圾回收算法和垃圾收集器的关系

    JAVAGC垃圾回收机制和常见垃圾回收算法 推荐博客:JVM垃圾回收机制和常见垃圾回收算法 JVM的内存结构.垃圾回收算法

  8. JavaGC垃圾回收机制和常见垃圾回收算法

    Java GC是在什么时候,对什么东西,做了什么事情?” 什么位置:大部分在堆中,还有方法区!!方法区的垃圾收集主要回收两部分内容:废弃常量和无用的类,当满了之后同样触发FullGC, HotSpot ...

  9. Java中的垃圾回收算法详解

    一.前言   前段时间大致看了一下<深入理解Java虚拟机>这本书,对相关的基础知识有了一定的了解,准备写一写JVM的系列博客,这是第二篇.这篇博客就来谈一谈JVM中使用到的垃圾回收算法. ...

随机推荐

  1. 日常问题: SQL优化

    日常开发中,除了开辟新项目,业务需求开发,一般还要做负责系统的日常运维.比如线上告警了,出bug了,必须及时修复.这天,运维反馈mysql cpu告警了,然后抓了该时间节点的慢sql日志,要开发分析解 ...

  2. 「学习笔记」字符串基础:Hash,KMP与Trie

    「学习笔记」字符串基础:Hash,KMP与Trie 点击查看目录 目录 「学习笔记」字符串基础:Hash,KMP与Trie Hash 算法 代码 KMP 算法 前置知识:\(\text{Border} ...

  3. liunx系统docker部署.net core3.1

    此篇文章演示基本的基于docker部署.netcore服务,liunx系统腾讯云ubuntu,.net core版本3.1. 1.安装docker apt install docker.io 2.拉取 ...

  4. Mac_linux_ssh防掉线

    vi ~/.ssh/config 加入一条 ServerAliveInterval 60 #客户端主动向服务端请求响应的间隔

  5. 基于 PyTorch 和神经网络给 GirlFriend 制作漫画风头像

    摘要:本文中我们介绍的 AnimeGAN 就是 GitHub 上一款爆火的二次元漫画风格迁移工具,可以实现快速的动画风格迁移. 本文分享自华为云社区<AnimeGANv2 照片动漫化:如何基于 ...

  6. Ubuntu22.04 安装配置流水账

    前两天为了测一个CH340的bug, 装了三遍20.04. bug解决完, 心想反正也要重新装各种软件, 不如直接装22.04吧. 把涉及的安装记录一下方便将来参考. 制作启动U盘 在Ubuntu网站 ...

  7. 我的Go并发之旅、01 并发哲学与并发原语

    注:本文所有函数名为中文名,并不符合代码规范,仅供读者理解参考. 上下文 上下文(Context)代表了程序(也可以是进程,操作系统,机器)运行时的环境和状态,联系程序整个生命周期与资源调用,是程序可 ...

  8. MySQL 数据更新过程

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247486441&idx=1&sn=fcf93709 ...

  9. Beats: Filebeat和pipleline processors

    简要来说: 使用filebeat读取log日志,在filebeat.yml中先一步处理日志中的个别数据,比如丢弃某些数据项,增加某些数据项. 按照之前的文档,是在filebeat.yml中操作的,具体 ...

  10. 2流高手速成记(之三):SpringBoot整合mybatis/mybatis-plus实现数据持久化

    接上回 上一篇我们简单介绍了基于SpringBoot实现简单的Web开发,本节来看Web开发中必不可少的内容--数据持久化 先看项目结构: 1. 创建数据表 打开mysql,打开数据库 test (没 ...