jvm之垃圾收集一之垃圾回收算法
最近又重新在读深入理解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之垃圾收集一之垃圾回收算法的更多相关文章
- Jvm垃圾收集器和垃圾回收算法
概述: 目前内存的动态分配和内存的回收技术已经相当成熟,一切看起来都已经进入了“自动化”时代,为什么还要去了解GC和内存分配呢?原因很简单:当需要排查各种内存泄漏.内存溢出问题时,当垃圾收集器成为系统 ...
- jvm学习笔记一(垃圾回收算法)
一:垃圾回收机制的原因 java中,当没有对象引用指向原先分配给某个对象的内存时候,该内存就成为了垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息 ...
- JVM虚拟机学习一:垃圾回收算法总结
1.java虚拟机中涉及到的数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型. 基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某 ...
- java虚拟机学习-JVM调优总结-基本垃圾回收算法(7)
可以从不同的的角度去划分垃圾回收算法: 1.按照基本回收策略分 引用计数(Reference Counting): 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计 ...
- 深入了解java虚拟机(JVM) 第六章 垃圾回收算法
一.标记清除算法 标记清除算法顾名思义,就是将需要回收的对象进行标记,然后进行清除.那么这个算法就有标记和清除两种过程.标记过程主要是通过可达性分析算法进行判断存活对象,然后遍历所有的对象来找到需要回 ...
- JVM G1垃圾回收算法简要介绍
JVM G1垃圾回收算法简要介绍 G1的特点 能够像CMS垃圾回收算法一样并发操作应用线程(潜台词:多核) 无需太长时间即可压缩空闲内存空间(潜台词:不会引起太多的GC停顿时间) 尽可能地让GC时长可 ...
- 6.GC垃圾回收算法和垃圾收集器的关系
JAVAGC垃圾回收机制和常见垃圾回收算法 推荐博客:JVM垃圾回收机制和常见垃圾回收算法 JVM的内存结构.垃圾回收算法
- JavaGC垃圾回收机制和常见垃圾回收算法
Java GC是在什么时候,对什么东西,做了什么事情?” 什么位置:大部分在堆中,还有方法区!!方法区的垃圾收集主要回收两部分内容:废弃常量和无用的类,当满了之后同样触发FullGC, HotSpot ...
- Java中的垃圾回收算法详解
一.前言 前段时间大致看了一下<深入理解Java虚拟机>这本书,对相关的基础知识有了一定的了解,准备写一写JVM的系列博客,这是第二篇.这篇博客就来谈一谈JVM中使用到的垃圾回收算法. ...
随机推荐
- Tomcat 10无法使用javax包
可以导入新的 jakarta包 <dependencies><!--servlet依赖--> <dependency> <groupId>jakarta ...
- Windows权限维持总结
windows权限维持 注册服务 sc create 服务名 binpath= "cmd.exe /k 木马路径" start="auto" obj=" ...
- 「学习笔记」倍增思想与lca
目录 ST表 算法 预处理 查询 关于 log2 Code 预处理 查询 例题 P2880 P2048 lca 树上 RMQ 前置知识:欧拉序列 算法 Code 离线 Tarjan 算法 Code 倍 ...
- Windows平台Unity3d播放多路RTMP或RTSP流
好多开发者在做AR.VR或者教育类产品时,苦于如何在windows平台构建一个稳定且低延迟的RTSP或者RTMP播放器,如果基于Unity3d完全重新开发一个播放器,代价大.而且周期长,不适合快速出产 ...
- Typora 最后免费版本也不能用了?简单一招搞定
作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 Typora是一款优秀的 Markdown 编辑 ...
- 【读书笔记】C#高级编程 第十九章 程序集
(一)程序集的含义 程序集是.NET用于部署和配置单元的术语. .NET应用程序包含一个或多个程序集.通常扩展名是EXE或DLL的.NET可执行程序称为程序集. 程序集是自我描述的安装单元,由一个或多 ...
- pat乙级每日习题
欢迎加入我们:qq群:1054587486 1:https://pintia.cn/problem-sets/994805260223102976/problems/99480532591848652 ...
- ConcurrentDictionary<T,V> 的这两个操作不是原子性的
好久不见,马甲哥封闭居家半个月,记录之前遇到的一件小事. ConcurrentDictionary<TKey,TValue>绝大部分api都是线程安全且原子性的, 唯二的例外是接收工厂委托 ...
- Memlab,一款分析 JavaScript 堆并查找浏览器和 Node.js 中内存泄漏的开源框架
Memlab 是一款 E2E 测试和分析框架,用于发现 JavaScript 内存泄漏和优化机会. Memlab 是 JavaScript 的内存测试框架.它支持定义一个测试场景(使用 Puppete ...
- 2021年3月-第03阶段-前端基础-JavaScript基础语法-JavaScript基础第01天
1 - 编程语言 1.1 编程 编程: 就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 计算机程序: 就是计算机所执行的一系列的指令集合,而程序全部都是用我们所掌 ...