JVM学习笔记——GC算法
GC 算法
GC 即 Garbage Collection 垃圾回收。JVM 中的 GC 99%发生在堆中,而 Java 堆中采用的垃圾回收机制为分代收集算法。即将堆分为新生代和老年代,根据不同的区域使用不同的垃圾回收算法。
1. 确认垃圾的算法
1.1 引用计数法
给每个对象设置一个引用计数器,每有一个地方引用此对象时,计数器 +1,引用失效计数器 -1。当对象计数器为0时,将会被垃圾回收。
引用计数器无法解决循环引用的问题。当AB两个对象都无其他对象引用,且 A 对象引用 B 对象,B 对象也引用 A 对象时,两个对象本应被回收,但计数器都不为0,无法垃圾回收。
因此主流虚拟机都未采用此算法。
1.2 可达性算法(引用链法)
从一个被视为 GC Roots 的对象开始向下搜索,如果一个对象到 GC Roots 没有任何引用链相连时,说明此对象不可用,可以被垃圾回收。
Java 中可作为 GC Roots 的对象如下:
虚拟机栈中引用的对象
方法区类静态属性引用的对象
方法区常量池引用的对象
本地方法栈 JNI 引用的对象
当一个对象不可达 GC Roots 时,这个对象不会立马被回收,而是处于死缓的阶段,若要真正被回收需要经历两次标记。
被第一次标记的对象会经历一次筛选,筛选是否有必要进行finalize()方法,对象如果已被虚拟机调用过或认定没必要执行finalize()方法,则立即回收。
如果需要执行finalize()方法,则把对象放入 F-Queue 队列中,等待Finalize()线程执行,该线程为低优先级,且不被 JVM 承诺执行完毕。GC对 F-Queue 队列中的对象进行二次标记,被标记后等待回收。
2. 垃圾回收算法
2.1 标记清除算法 Mark-Sweep
最基础的垃圾回收算法,分两个阶段,标记,清除。标记所需回收的对象,清除被标记的对象。
看似简单,但该算法最大的问题在于内存碎片化严重,如果清理后不整理内存,整块内存就会被存活的对象分割成一块块较小的连续空间,当需要创建较大对象时会难以在内存中找到合适的连续空间。
节约空间
需要进行两次扫描,耗时严重
内存碎片化严重
老年代标记清除,标记压缩结合使用
2.2 复制算法 Copying
为了解决标记清除算法内存碎片化的缺陷而被提出。
按内存容量将内存划分为两块,每次只使用其中一块,当一块内存存满后,将存活的对象复制至另一块,清空当前块内的内存,然后两边互换使用。
算法实现简单,内存效率高,不易产生碎片
使用空间被压缩,浪费了一点空间,如果存活对象增多,算法效率会大大降低
2.3 标记整理算法 Mark-Compact
结合标记清除算法和复制算法被提出。
算法思想:
标记死亡对象
将存活对象移动至内存另一端
清除端边界外所有对象

特点:
内存连续,不产生碎片
效率不高,要标记存活对象,整理对象引用地址,效率低于复制算法
老年代标记清除,标记压缩结合使用
JVM学习笔记——GC算法的更多相关文章
- JVM学习笔记——GC垃圾收集器
GC 垃圾收集器 Java 堆内存采用分代回收算法,因此 JVM 针对新生代和老年代提供了多种垃圾收集器. 1. Serial 收集器 Serial 收集器是单线程收集器,采用复制算法. 是最基本的垃 ...
- 【Java虚拟机】JVM学习笔记之GC
JVM学习笔记二之GC GC即垃圾回收,在C++中垃圾回收由程序员自己来做,例如可以用free和delete来回收对象.而在Java中,JVM替程序员来执行垃圾回收的工作,下面看看GC的详细原理和执行 ...
- java之jvm学习笔记十三(jvm基本结构)
java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...
- jvm内存JVM学习笔记-引用(Reference)机制
在写这篇文章之前,xxx已经写过了几篇关于改jvm内存主题的文章,想要了解的朋友可以去翻一下之前的文章 如果你还不了解JVM的基本概念和内存划分,请阅读JVM学习笔记-基础知识和JVM学习笔记-内存处 ...
- JVM学习笔记-第三章-垃圾收集器与内存分配策略
JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...
- JVM学习笔记——垃圾回收篇
JVM学习笔记--垃圾回收篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的垃圾回收部分 我们会分为以下几部分进行介绍: 判断垃圾回收对象 垃圾回收算法 分代垃圾回收 垃圾回收器 ...
- JVM学习笔记(四)------内存调优【转】
转自:http://blog.csdn.net/cutesource/article/details/5907418 版权声明:本文为博主原创文章,未经博主允许不得转载. 首先需要注意的是在对JVM内 ...
- JVM学习笔记(四)------内存调优
首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
随机推荐
- opengl中标准矩形像素点手动网格化为三角形条带的实现
这里以一张矩形图片为例进行说明: 一张图片的像素点是孤立的,导入opengl中进行绘制出来,看起来没问题,但是当我们放大图片时候,显示的就是一个个孤立的点,而没有像看图软件放大图片那样看起来还是连续的 ...
- SpringBoot整合定时任务----Scheduled注解实现(一个注解全解决)
一.使用场景 定时任务在开发中还是比较常见的,比如:定时发送邮件,定时发送信息,定时更新资源,定时更新数据等等... 二.准备工作 在Spring Boot程序中不需要引入其他Maven依赖 (因为s ...
- JDK1.8源码(八)——java.util.HashMap类
https://www.cnblogs.com/javastack/p/12801870.html https://www.cnblogs.com/chanshuyi/p/java_collectio ...
- vue父组件中调用子组件的方法
Vue项目中如何在父组件中直接调用子组件的方法: 方案一:通过ref直接调用子组件的方法: //父组件中 <template> <div> <Button @click= ...
- jsPlumb开发流程设计器
前言 jsPlumb是一款开源软件,但jsPlumb toolkit是收费的. 本文主要使用jsPlumb实现一些简单的流程设计功能. 基础学习 首先引入jsplumb.min.js. <scr ...
- Azure 实践(4)- CI/CD .netcore项目Docker构建及部署
上篇已介绍了.netcore项目构建的相关步骤,本篇继续完善 1.什么是CI/CD CI/CD 中的"CI"始终指持续集成,它属于开发人员的自动化流程.成功的 CI 意味着应用代码 ...
- 255 day03_List、Set、数据结构、Collections
day03 [List.Set.数据结构.Collections] 主要内容 数据结构 List集合 Set集合 Collections 教学目标 [ ] 能够说出List集合特点 [ ] 能够说出常 ...
- Anaconda配置国内镜像源
1. 为conda配置(清华)镜像源 使用conda进行安装时,访问的是国外的网络,所以下载和安装包时会特别慢.我们需要更换到国内镜像源地址,这里我更换到国内的清华大学地址.(永久添加镜像) Wind ...
- cnblogs-theme-silence 主题设置简约风格
本文参考 更改博客皮肤 更改博客皮肤为Custom 页面定制CSS代码 勾选禁用模板默认CSS 导入复制该文件内容到代码框中 配置代码块复制功能 样式 和 右侧滑动条样式 /*复制功能添加按钮 beg ...
- 对象继承深入、call_apply、圣杯模式、构造函数和闭包,企业模块化
一个实现加减乘除的插件: 原型其实是在构造函数之上的,构造函数变成实例化函数的时候才会有原型, 原型实际上是构造函数的一个属性 原型无非就是2个字:继承 原型中继承父类所有方法是很不合理的,因为没 ...