最近又重新在读深入理解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. 【Matlab】学习记录1-简单的函数介绍

    sind(30) %正弦函数,以角度为单位  ans =0.5000 exp(2) %以e为底的指数函数,即e^x   ans =7.3891 log10(10)  ans =1log(exp(1)) ...

  2. k8s命令补全方法

    正常安装了k8s后,使用kubect 工具后接的命令不能直接tab补全 命令补全方法: yum -y install bash-completionsource /usr/share/bash-com ...

  3. iNeuOS工业互联网操作系统,面向4个领域颁发第一批技术认证资质

    为了更好的紧密合作.利益多赢和共建生态.iNeuOS工业互联网操作系统面向:仪器仪表.双碳环保.核能科学与工程和钢铁冶金领域颁发第一批技术认证资质,一共21名同志在项目实施过程中表现突出,从iNeuO ...

  4. 从 Hadoop 到云原生, 大数据平台如何做存算分离

    Hadoop 的诞生改变了企业对数据的存储.处理和分析的过程,加速了大数据的发展,受到广泛的应用,给整个行业带来了变革意义的改变:随着云计算时代的到来, 存算分离的架构受到青睐,企业开开始对 Hado ...

  5. 如何写成高性能的代码(一):巧用Canvas绘制电子表格

    一.什么是Canvas Canvas是HTML5的标签,是HTML5的一种新特性,又称画板.顾名思义,我们可以将其理解为一块画布,支持在上面绘制矩形.圆形等图形或logo等. 需要注意的是,与其他标签 ...

  6. Flink基础概念入门

    Flink 概述 什么是 Flink Apache Apache Flink 是一个开源的流处理框架,应用于分布式.高性能.高可用的数据流应用程序.可以处理有限数据流和无限数据,即能够处理有边界和无边 ...

  7. (数据科学学习手札143)为geopandas添加gdb文件写出功能

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,很多读者朋友跟随着我先前写作的 ...

  8. ProxySQL(6):管理后端节点

    文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9286922.html 配置后端节点前的说明 为了让ProxySQL能够找到后端的MySQL节点,需要将后端的 ...

  9. ECON 模式

    ECON模式通过调节发动机和空调系统的性能,有效提高燃油经济性. 在D行驶档的时候开启

  10. PHP全栈开发(一):CentOS 7 配置LAMP

    服务器CentOS7 IP地址:10.28.2.249 进行网络配置 可以使用ip address命令查看当前的网卡状态 两张网卡,一张lo网卡一张ens160网卡 Ens160这个网卡的配置文件为/ ...