java-垃圾回收与算法

垃圾回收与算法

1. 如何确定垃圾

1. 引用计数法

  在 Java 中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单的办法是通过引用计数来判断一个对象是否可以回收。简单说,即一个对象如果没有任何与之关联的引用,即他们的引用计数都不为 0,则说明对象不太可能再被用到,那么这个对象就是可回收对象。

2. 可达性分析

 为了解决引用计数法的循环引用问题,Java 使用了可达性分析的方法。通过一系列的“GC roots”对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。

  要注意的是,不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记过程。两次标记后仍然是可回收对象,则将面临回收。

2. 标记清除算法( Mark-Sweep)

  最基础的垃圾回收算法,分为两个阶段,标注和清除。标记阶段标记出所有需要回收的对象,清除阶段回收被标记的对象所占用的空间。
在这里插入图片描述

  从图中我们就可以发现,该算法最大的问题是内存碎片化严重,后续可能发生大对象不能找到可利用空间的问题。

3. 复制算法(copying)

  为了解决 Mark-Sweep 算法内存碎片化的缺陷而被提出的算法。按内存容量将内存划分为等大小的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用的内存清掉,
在这里插入图片描述

  这种算法虽然实现简单,内存效率高,不易产生碎片,但是最大的问题是可用内存被压缩到了原本的一半。且存活对象增多的话,Copying 算法的效率会大大降低。

4. 标记整理算法(Mark-Compact)

  结合了以上两个算法,为了避免缺陷而提出。标记阶段和 Mark-Sweep 算法相同,标记后不是清理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象。
在这里插入图片描述

5. 分代收集算法

  分代收集法是目前大部分 JVM 所采用的方法,其核心思想是根据对象存活的不同生命周期将内存划分为不同的域,一般情况下将 GC 堆划分为老生代(Tenured/Old Generation)和新生代(YoungGeneration)。老生代的特点是每次垃圾回收时只有少量对象需要被回收,新生代的特点是每次垃圾回收时都有大量垃圾需要被回收,因此可以根据不同区域选择不同的算法。

5.1. 新生代与复制算法

  目前大部分 JVM 的 GC 对于新生代都采取 Copying 算法,因为新生代中每次垃圾回收都要回收大部分对象,即要复制的操作比较少,但通常并不是按照 1:1 来划分新生代。一般将新生代划分为一块较大的 Eden 空间和两个较小的 Survivor 空间(From Space, To Space),每次使用Eden 空间和其中的一块 Survivor 空间,当进行回收时,将该两块空间中还存活的对象复制到另一块 Survivor 空间中。
在这里插入图片描述

5.2. 老年代与标记复制算法

  而老年代因为每次只回收少量对象,因而采用 Mark-Compact 算法。

  1. JAVA 虚拟机提到过的处于方法区的永生代(Permanet Generation),它用来存储 class 类,常量,方法描述等。对永生代的回收主要包括废弃常量和无用的类。
  2. 对象的内存分配主要在新生代的 Eden Space 和 Survivor Space 的 From Space(Survivor 目前存放对象的那一块),少数情况会直接分配到老生代。
  3. 当新生代的 Eden Space 和 From Space 空间不足时就会发生一次 GC,进行 GC 后,EdenSpace 和 From Space 区的存活对象会被挪到 To Space,然后将 Eden Space 和 FromSpace 进行清理。
  4. 如果 To Space 无法足够存储某个对象,则将这个对象存储到老生代。
  5. 在进行 GC 后,使用的便是 Eden Space 和 To Space 了,如此反复循环。
  6. 当对象在 Survivor 区躲过一次 GC 后,其年龄就会+1。默认情况下年龄到达 15 的对象会被移到老生代中。

GC 分代收集算法 VS 分区收集算法

1. 分代收集算法

  当前主流 VM 垃圾收集都采用”分代收集”(Generational Collection)算法, 这种算法会根据对象存活周期的不同将内存划分为几块, 如 JVM 中的 新生代、老年代、永久代,这样就可以根据各年代特点分别采用最适当的 GC 算法

1.1. 在新生代-复制算法

  每次垃圾收集都能发现大批对象已死, 只有少量存活. 因此选用复制算法, 只需要付出少量存活对象的复制成本就可以完成收集.

1.2. 在老年代-标记整理算法

  因为对象存活率高、没有额外空间对它进行分配担保, 就必须采用“标记—清理”或“标记—整理”算法来进行回收, 不必进行内存复制, 且直接腾出空闲内存.

2. 分区收集算法

  分区算法则将整个堆空间划分为连续的不同小区间, 每个小区间独立使用, 独立回收. 这样做的好处是可以控制一次回收多少个小区间 , 根据目标停顿时间, 每次合理地回收若干个小区间(而不是整个堆), 从而减少一次 GC 所产生的停顿。

GC 垃圾收集器

  Java 堆内存被划分为新生代和年老代两部分,新生代主要使用复制和标记-清除垃圾回收 算法 ;年老代主要使用标记-整理垃圾回收算法,因此 java 虚拟中针对新生代和年老代分别提供了多种不同的垃圾收集器,JDK1.6 中 Sun HotSpot 虚拟机的垃圾收集器如下:

1. Serial 垃圾收集器(单线程、复制算法)

  Serial(英文连续)是最基本垃圾收集器,使用复制算法,曾经是 JDK1.3.1 之前新生代唯一的垃圾收集器。Serial 是一个单线程的收集器,它不但只会使用一个 CPU 或一条线程去完成垃圾收集工作,并且在进行垃圾收集的同时,必须暂停其他所有的工作线程,直到垃圾收集结束。Serial 垃圾收集器虽然在收集垃圾过程中需要暂停所有其他的工作线程,但是它简单高效,对于限定单个 CPU 环境来说,没有线程交互的开销,可以获得最高的单线程垃圾收集效率,因此 Serial垃圾收集器依然是 java 虚拟机运行在 Client 模式下默认的新生代垃圾收集器。

2. ParNew 垃圾收集器(Serial+多线程)

  ParNew 垃圾收集器其实是 Serial 收集器的多线程版本,也使用复制算法,除了使用多线程进行垃圾收集之外,其余的行为和 Serial 收集器完全一样,ParNew 垃圾收集器在垃圾收集过程中同样也要暂停所有其他的工作线程。

  ParNew 收集器默认开启和 CPU 数目相同的线程数,可以通过-XX:ParallelGCThreads 参数来限制垃圾收集器的线程数。【Parallel:平行的】
  ParNew 虽然是除了多线程外和 Serial 收集器几乎完全一样,但是 ParNew 垃圾收集器是很多 java
虚拟机运行在 Server 模式下新生代的默认垃圾收集器。

3. Parallel Scavenge 收集器(多线程复制算法、高效)

  Parallel Scavenge 收集器也是一个新生代垃圾收集器,同样使用复制算法,也是一个多线程的垃圾收集器,它重点关注的是程序达到一个可控制的吞吐量(Thoughput,CPU 用于运行用户代码的时间/CPU 总消耗时间,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)),高吞吐量可以最高效率地利用 CPU 时间,尽快地完成程序的运算任务,主要适用于在后台运算而不需要太多交互的任务。自适应调节策略也是 ParallelScavenge 收集器与 ParNew 收集器的一个重要区别。

4. Serial Old 收集器(单线程标记整理算法 )

  Serial Old 是 Serial 垃圾收集器年老代版本,它同样是个单线程的收集器,使用标记-整理算法,这个收集器也主要是运行在 Client 默认的 java 虚拟机默认的年老代垃圾收集器。
在 Server 模式下,主要有两个用途:

  1. 在 JDK1.5 之前版本中与新生代的 Parallel Scavenge 收集器搭配使用。
  2. 作为年老代中使用 CMS 收集器的后备垃圾收集方案。

  新生代 Parallel Scavenge 收集器与 ParNew 收集器工作原理类似,都是多线程的收集器,都使用的是复制算法,在垃圾收集过程中都需要暂停所有的工作线程。

5. Parallel Old 收集器(多线程标记整理算法)

  Parallel Old 收集器是 Parallel Scavenge 的年老代版本,使用多线程的标记-整理算法,在 JDK1.6才开始提供。
  在 JDK1.6 之前,新生代使用 ParallelScavenge 收集器只能搭配年老代的 Serial Old 收集器,只能保证新生代的吞吐量优先,无法保证整体的吞吐量,Parallel Old 正是为了在年老代同样提供吞吐量优先的垃圾收集器,如果系统对吞吐量要求比较高,可以优先考虑新生代 Parallel Scavenge和年老代 Parallel Old 收集器的搭配策略。

6. CMS 收集器(多线程标记清除算法)

  Concurrent mark sweep(CMS)收集器是一种年老代垃圾收集器,其最主要目标是获取最短垃圾回收停顿时间,和其他年老代使用标记-整理算法不同,它使用多线程的标记-清除算法。
最短的垃圾收集停顿时间可以为交互比较高的程序提高用户体验。
CMS 工作机制相比其他的垃圾收集器来说更复杂,整个过程分为以下 4 个阶段:

6.1. 初始标记

  只是标记一下 GC Roots 能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。

6.2. 并发标记

  进行 GC Roots 跟踪的过程,和用户线程一起工作,不需要暂停工作线程。

6.3. 重新标记

  为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程。

6.4. 并发清除

  清除 GC Roots 不可达对象,和用户线程一起工作,不需要暂停工作线程。由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,所以总体上来看CMS 收集器的内存回收和用户线程是一起并发地执行。

7. G1 收集器

Garbage first 垃圾收集器是目前垃圾收集器理论发展的最前沿成果,相比与 CMS 收集器,G1 收集器两个最突出的改进是:

  1. 基于标记-整理算法,不产生内存碎片。
  2. 可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。

   G1 收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域
的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾
最多的区域。区域划分和优先级区域回收机制,确保 G1 收集器可以在有限时间获得最高的垃圾收
集效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/78719.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于YOLOv5n/s/m不同参数量级模型开发构建茶叶嫩芽检测识别模型,使用pruning剪枝技术来对模型进行轻量化处理,探索不同剪枝水平下模型性能影响【续】

这里主要是前一篇博文的后续内容,简单回顾一下:本文选取了n/s/m三款不同量级的模型来依次构建训练模型,所有的参数保持同样的设置,之后探索在不同剪枝处理操作下的性能影响。 在上一篇博文中保持30的剪枝程度得到的效果还是比较理…

Qt平滑弹出页面

目标功能&#xff1a; (1)按下btn&#xff0c;弹出绿色页面。 (2)按下btn2,绿色页面隐藏。 (3)按下左边余下的区域&#xff0c;绿色页面也隐藏。 (4)平滑地显示和隐藏 效果&#xff1a; form.h #ifndef FORM_H #define FORM_H#include <QWidget>namespace Ui { class…

如何将labelImg打包成exe

最近整理一下数据标注这块的内容&#xff0c;在目标检测和目标分割里面用的最多的标注工具labelimg&#xff0c;labelme labelimg主要用于目标检测领域制作自己的数据集&#xff0c;如&#xff1a;YOLO系列目标检测模型 labelme主要用于图像分割领域制作自己的数据集&#xf…

IDEA 设置为护眼的豆沙绿

代码区域设置成护眼色 先打开 IDEA 的设置界面&#xff0c;然后按照下图按顺序店了设置就可以了 这个时候&#xff0c;可以看到&#xff0c;只有代码区域别成了护眼色&#xff0c;其他地方还是白的刺眼&#xff0c;我们来一个一个的解决掉 左侧的文件页修改为护眼色 还是先…

WPF 界面结构化处理

文章目录 概要一、xaml界面结构化处理二、逻辑树与视觉树 概要 WPF 框架是开源的&#xff0c;但是不能跨平台&#xff0c;可以使用MAUI&#xff0c;这个框架可以跨平台&#xff0c;WPF源码可以在github上下载&#xff0c;下载地址&#xff1a;https://gitbub.com/dotnet/wpf。…

5G智能网关助力打造数字乡村物联网

乡村振兴&#xff0c;网络先行&#xff0c;信息通信技术赋能农业农村现代化发展的作用日益彰显&#xff0c;也成为实施乡村振兴战略的重要力量。 截止今年三月&#xff0c;我国5G网络已经覆盖全国所有地级市、县城城区及数万行政村&#xff0c;农村光纤平均下载速率超过100Mb/s…

每天一道leetcode:剑指 Offer 64. 求1+2+…+n(中等递归)

今日份题目&#xff1a; 求 12...n &#xff0c;要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句&#xff08;A?B:C&#xff09;。 示例1 输入: n 3 输出: 6 示例2 输入: n 9 输出: 45 提示 1 < n < 10000 题目思路 使用递归…

阿里云服务器镜像大全_Linux和Windows操作系统清单

阿里云服务器操作系统大全&#xff0c;阿里云提供的镜像均为正版授权&#xff0c;正版镜像可以在云服务器ECS上运行的应用程序提供安全、稳定的运行环境系统&#xff0c;阿里云服务器以公共镜像为例分享阿里云服务器操作系统大全&#xff0c;包括Alibaba Cloud Linux镜像、Linu…

JAVAIO流

// 【I/O】input output &#xff1a;Java对系统中的文件系统的支持 // 【i/o体系】&#xff1a; // 1.处理单位&#xff1a;字节流&#xff0c;字符流 // 2.处理流向&#xff1a;输入流&#xff0c;输出流 // 3.处理功能&#xff1a;节…

设计模式之工厂方法模式(FactoryMethod)

一、概述 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。 二、适用性 1.当一个类不知道它所必须创建的对象的类的时候。 2.当一个类希望由它的子类来指定它所创建的对象的时候。 3.当类将创建对象的职责委…

idea入门与maven配置的一些介绍

idea入门与maven配置的一些介绍 1.确保Java和Maven已安装2.创建一个新的Maven项目3.导航到要创建项目的目录配置Maven4.配置项目的pom.xml文件5.配置其他Tomcat和设置jdk6.构建和运行项目 关于idea入门基础配置 步骤1&#xff1a;安装IntelliJ IDEA 首先&#xff0c;从IntelliJ…

matlab保存图片

仅作为记录&#xff0c;大佬请跳过。 文章目录 用界面中的“另存为”用saveas 用界面中的“另存为” 即可。 参考 感谢大佬博主文章&#xff1a;传送门 用saveas 必须在编辑器中的plot之后用saveas&#xff08;也就是不能在命令行中单独使用——比如在编辑器中plot&#xf…

【图像分类】基于卷积神经网络和主动学习的高光谱图像分类(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Genoss GPT简介:使用 Genoss 模型网关实现多个LLM模型的快速切换与集成

一、前言 生成式人工智能领域的发展继续加速&#xff0c;大型语言模型 (LLM) 的用途范围不断扩大。这些用途跨越不同的领域&#xff0c;包括个人助理、文档检索以及图像和文本生成。ChatGPT 等突破性应用程序为公司进入该领域并开始使用这项技术进行构建铺平了道路。 大公司正…

HarmonyOS/OpenHarmony应用开发-ArkTS语言渲染控制ForEach循环渲染

ForEach基于数组类型数据执行循环渲染。说明&#xff0c;从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 一、接口描述 ForEach(arr: any[], itemGenerator: (item: any, index?: number) > void,keyGenerator?: (item: any, index?: number) > stri…

做一个超简单的Python运行

作为一名专业的爬虫代理产品供应商&#xff0c;我知道很多人对Python爬虫有兴趣&#xff0c;但可能不知道该从何处入手。今天&#xff0c;我就来分享一个超简单的Python爬虫入门教程&#xff0c;希望能帮助到你们&#xff01;快点准备起来&#xff0c;让我们开始吧&#xff01;…

【数据结构】链表常见题目

文章目录 链表合并两个有序链表反转链表复制带随机指针的链表环形链表环形链表II相交链表移除链表元素链表中倒数第k个节点链表分割链表的回文结构链表的中间节点旋转链表链表排序链表求和 (逆序求)链表求和II (正序求)重排链表奇偶链表反转链表II <==> 链表内指定区间反…

【学习日记】【FreeRTOS】任务调度时如何考虑任务优先级——任务的自动切换

写在前面 本文开始为 RTOS 加入考虑任务优先级的自动调度算法&#xff0c;代码大部分参考野火。 本文主要是一篇学习笔记&#xff0c;加入了笔者自己对野火代码的梳理和理解。 一、基本思路 首先我们要知道&#xff0c;在 RTOS 中&#xff0c;优先级越高、越需要被先执行的的…

leetcode 917.仅仅反转字母

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;仅仅反转字母 ps&#xff1a; 这道题思路很简单&#xff0c;只需要一个下标在前一个下标在后&#xff0c;分别找是字母的字符&#xff0c;找到之后交换即可。 代码&#xff1a; class Solution { public:bool isAlpha …

【数据结构OJ题】环形链表II

原题链接&#xff1a;https://leetcode.cn/problems/linked-list-cycle-ii/description/ 1. 题目描述 2. 思路分析 如果链表存在环&#xff0c;则fast和slow会在环内相遇&#xff0c;定义相遇点到入口点的距离为X&#xff0c;定义环的长度为C&#xff0c;定义头到入口的距离为…