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中使用到的垃圾回收算法. ...
随机推荐
- HDU4372 Count the Buildings (+题解:斯特林数)
题面 (笔者翻译) There are N buildings standing in a straight line in the City, numbered from 1 to N. The h ...
- HTML+JS+CSS 实现随机跳转到一个网址
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http ...
- 通过宏封装实现std::format编译期检查参数数量是否一致
背景 std::format在传参数量少于格式串所需参数数量时,会抛出异常.而在大部分的应用场景下,参数数量不一致提供编译报错更加合适,可以促进我们更早发现问题并进行改正. 最终效果 // 测试输出接 ...
- SpringMVC 02: SpringMVC响应get和post请求 + 5种获取前端数据的方式
响应get和post请求 SpringMVC中使用@RequestMapping注解完成对get请求和post请求的响应 项目结构和配置文件与SpringMVC博客集中的"SpringMVC ...
- mydodo协议
mydodo协议 目录 数据帧结构 命令 协议 代码样例 数据帧结构 帧头1 帧头2 设备号 命令 数据长度 数据 0x4D 0x59 xxx cmd nByte data 例子:设备my01 的继电 ...
- 【设计模式】Java设计模式 - 动态代理
[设计模式]Java设计模式 - 动态代理 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 最近工作比较忙,没啥时间学习 目录 [设计模 ...
- git reset总结
git reset git 的重置操作 有三种模式:hard.mixed(默认).soft 1. hard 用法 hard会重置stage区和工作区,和移动代码库上HEAD 和branch的指针所指向 ...
- 【Vue学习笔记】—— vuex的语法 { }
学习笔记 作者:o_Ming vuex Vuex ++ state ++ (用于存储全局数据) 组件访问 state 中的全局数据的方式1: this.$store.state.全局数据 组件访问 s ...
- ELK接收paloalto防火墙威胁日志并定位城市展示
ELK接收paloalto防火墙威胁日志并定位城市展示 一.准备环境: 搭建好的ELK环境 palo alto防火墙(企业用的) 二.安装logstash并做好过滤 将palo alto日志打到一台c ...
- Go语言学习的坑爹历程
鄙人暑期实习,需要用Go语言进行编程 在go语言中,结构体的定义只支持变量的声明,成员函数是采用"接口方法"来实现的 留一个成员定义的模板在此 package main impor ...