什么是 Java 垃圾回收器~

news2024/9/21 4:29:26

什么是 Java 垃圾回收器

Java 垃圾回收器是 Java 虚拟机 (JVM) 的三个重要模块 (另外两个是解释器和多线程机制) 之一,为应用程序提供内存的自动分配 (Memory Allocation)、自动回收 (Garbage Collect) 功能,这两个操作都发生在 Java 堆上 (一段内存快)。某一个时点,一个对象如果有一个以上的引用 (Rreference) 指向它,那么该对象就为活着的 (Live),否则死亡 (Dead),视为垃圾,可被垃圾回收器回收再利用。垃圾回收操作需要消耗 CPU、线程、时间等资源,所以容易理解的是垃圾回收操作不是实时的发生 (对象死亡马上释放),当内存消耗完或者是达到某一个指标 (Threshold, 使用内存占总内存的比列,比如 0.75) 时,触发垃圾回收操作。有一个对象死亡的例外,java.lang.Thread 类型的对象即使没有引用,只要线程还在运行,就不会被回收。

回收的机制

依据统计分析可知,Java (包括一些其它高级语言) 里面大多数对象生命周期都是短暂的,所以把 Java 内存分代管理。分代的目的无非就是为不同代的内存块运用不同的管理策略 (算法),从而最大化性能。相对于年老代,通常年轻代要小很多,回收的频率高,速度快。年老代则回收频率低,耗时长。内存在年轻代里面分配,年轻代里面的对象经过多个回收周期依然存活的会自动晋升到年老代。

设计选型 (Design Choices)

设计选型影响 JVM 垃圾回收器的实现难度,以及 JVM 的性能指标,适用于不同的场景。描述的是回收算法的风格特点。

单线程串行回收 VS 多线程并行回收

回收操作自身是否多线程处理的问题。单线程回收的优点是简单,易实现,碎片少,适用于单核的机器。多线程并行回收在多核机器上面可以充分的利用 CPU 资源,减少回收的时间,增加生产力,缺点是复杂且可能有部分碎片没有回收。

回收时暂停应用线程 VS 回收和应用并发进行

回收操作时是否暂停应用线程的问题。暂停应用线程的优点是简单、准确、清理得比较干净、清理的时间也短 (CPU 资源独占),缺点是暂停应用线程之后会造成垃圾回收周期内应用的回应时间拉长,实时性非常高的系统比较敏感。回收和应用线程并行处理的优点是应用反应时间比较平稳、缺点是实现难度大、清理频率高、可能有碎片。

不合并释放的内存片段 VS 合并释放的内存片段 VS 把活着的复制到新的地方

这三个选型描述的是如何管理死亡的内存块片段。死亡的内存片段通常散落在堆的各个地方,如果不加以管理会有两个问题,内存分配的时候因查找可用的内存而导致速度慢,小的碎片会导致内存的浪费 (比如大的数组要求大的连续内存片段)。管理有两种方式,把活着的内存挪到内存块的某一端,记录可用内存的开始位置,或者干脆把活着的内存复制到一个新的内存区域,原来的内存块整个空出来。

性能指标 (Performance Metrics)

  • 生产率 (Throughput)
    一个较长的周期 (长的周期才有意义) 内,非回收时间占总时间的比率。度量系统的运行效率。

  • 垃圾回收花费 (Garbage Collection overhead)
    一个较长的周期内,回收时间占总时间的比率。与生产率相对应,加起来为 100%。

  • 暂停时间间隔 (Pause time)
    Java 虚拟机在回收垃圾的时候,有的算法会暂停所有应用线程的执行,某些系统可能对暂停的时间间隔比较敏感。

  • 回收的频率 (Frequency of collection)
    平均多久会发生回收操作。

  • 内存占用的大小 (Footprint)
    如堆的大小。

  • 实时性 (Promptness)
    自一个对象死亡起,经过多久该对象所占用内存被回收。

垃圾回收的类型

所有的回收器类型都是基于分代技术。Java HotSpot 虚拟机包含三代,年轻代 (Young Generation)、年老代 (Old Generation)、永久代 (Permanent Generation)。

  • 永久代
    存储类、方法以及它们的描述信息。可以通过 -XX:PermSize=64m 和 -XX:MaxPermSize=128m 两个可选项指定初始大小和最大值。通常 我们不需要调节该参数,默认的永久代大小足够了,不过如果加载的类非常多,不够用了,调节最大值即可。

  • 年老代 
    主要存储年轻代中经过多个回收周期仍然存活从而升级的对象,当然对于一些大的内存分配,可能也直接分配到永久代 (一个极端的例子是年轻代根本就存不下)。

  • 年轻代
    绝大多数的内存分配回收动作都发生在年轻代。如下图所示,年轻代被划分为三个区域,原始区 (Eden) 和两个小的存活区 (Survivor),两个存活区按功能分为 From 和 To。绝大多数的对象都在原始区分配,超过一个垃圾回收操作仍然存活的对象放到存活区。

串行回收器 (Serial Collector)

单线程执行回收操作,回收期间暂停所有应用线程的执行,client 模式下的默认回收器,通过 -XX:+UseSerialGC 命令行可选项强制指定。

  • 年轻代的回收算法 (Minor Collection)
    把 Eden 区的存活对象移到 To 区,To 区装不下直接移到年老代,把 From 区的移到 To 区,To 区装不下直接移到年老代,From 区里面年龄很大的升级到年老代。 回收结束之后,Eden 和 From 区都为空,此时把 From 和 To 的功能互换,From 变 To,To 变 From,每一轮回收之前 To 都是空的。设计的选型为复制。

  • 年老代的回收算法 (Full Collection)
    年老代的回收分为三个步骤,标记 (Mark)、清除 (Sweep)、合并 (Compact)。标记阶段把所有存活的对象标记出来,清除阶段释放所有死亡的对象,合并阶段 把所有活着的对象合并到年老代的前部分,把空闲的片段都留到后面。设计的选型为合并,减少内存的碎片。

并行回收器 (Parallel Collector)

使用多个线程同时进行垃圾回收,多核环境里面可以充分的利用 CPU 资源,减少回收时间,增加 JVM 生产率,Server 模式下的默认回收器。与串行回收器相同,回收期间暂停所有应用线程的执行。通过 -XX:+UseParallelGC 命令行可选项强制指定。

  • 年轻代的回收算法 (Minor Collection)
    使用多个线程回收垃圾,每一个线程的算法与串行回收器相同。

  • 年老代的回收算法 (Full Collection)
    年老代依然是单线程的,与串行回收器相同。

并行合并收集器 (Parallel Compacting Collection)

年轻代和年老代的回收都是用多线程处理。通过命令可选项 -XX:+UseParallelOldGC 指定,–XX:ParallelGCThreads=3 还可进一步指定参与并行回收的线程数。与串行回收器相同,回收期间暂停所有应用线程的执行。与并行回收器相比,年老代的回收时间更短,从而减少了暂停时间间隔 (Pause time)。通过–XX:+UseParallelOldGC 命令行可选项强制指定。

  • 年轻代的回收算法 (Minor Collection)
    与并行回收器 (Parallel Collector) 相同

  • 年老代的回收算法 (Full Collection) 
    年老代分为三个步骤,标记、统计、合并。这里用到分的思想,把年老代划分为很多个固定大小的区 (region)。 标记阶段,把所有存活的对象划分为 N 组 (应该与回收线程数相同),每一个线程独立的负责自己那一组,标记存活对象的位置以及 所在区 (Region) 的存活率信息,标记为并行的。统计阶段,统计每一个区 (Region) 的存活率,原则上靠前面的存活率较高,从前到后, 找到值得合并的开始位置 (绝大多数对象都存活的区不值得合并),统计阶段是串行的 (单线程)。合并阶段,依据统计阶段的信息,多线程 并行的把存活的对象从一个区 (Region) 复制到另外一个区 (Region)。

并发标记清除回收器 (Concurrent Mark-Sweep Collector)

又名低延时收集器 (Low-latency Collector),通过各种手段使得应用程序被挂起的时间最短。基本与应用程序并发地执行回收操作,没有合并和复制操作。通过命令行 -XX:+UseConcMarkSweepGC 指定,在单核或者双核系统里面还可以指定使用增量式回收模式 -XX:+UseConcMarkSweepGC。增量式回收是指把回收操作分为多个片段,执行一个片段之后释放 CPU 资源给应用程序,未来的某个时点接着上次的结果继续回收下去。目的也是减少延时。

  • 年轻代的回收算法 (Minor Collection)
    与并行回收器 (Parallel Collector) 相同

  • 年老代的回收算法 (Full Collection) 
    分为四个步骤,初始标记 (Initial Mark)、并发标记 (Concurrent Mark)、再次标记 (Remark)、以及并发清理 (Concurrent Sweep)。特别注意,没有合并操作,所以会有碎片。

  • 初始化阶段:暂停应用线程,找出所有存活的对象,耗时比较短,回收器使用单线程。

  • 并发标记阶段:回收器标记操作与应用并发运行,回收器使用单线程标记存活对象。

  • 再次标记:并发标记阶段由于应用程序也在运行,这个过程中可能新增或者修改对象。所以再次暂停应用线程,找出所有修改的对象,使用多线程标记。

  • 并发清理:回收器清理操作与应用并发运行,回收器使用单线程清理死亡对象。

Java 垃圾回收器的性能评估工具

  • –XX:+PrintGCDetails 和–XX:+PrintGCTimeStamps
    垃圾回收的开始时间,持续时间,每一代的空余内存等信息。

  • jmap [options] pid
    jamp 2043 查看 2043 进程里面已经加载的共享对象。通常 DLL 文件。
    jmap -heap 2043 查看内存堆的配置信息以及使用情况。
    jmap -permstat 2043 查看永久代的加载情况。
    jmap -histo 2043 查看类的加载和内存占用情况。

  • jstat [options] pid
    jstat -class 2043 class 加载、卸载、内存占用情况。
    jstat -gc 2043 GC 执行情况。

后记

Java 提供自动选择和自动性能优化功能。在做垃圾回收器调优之前,先列出所关注的性能指标,通过命令行告诉 JVM 你所关注的性能指标,由 JVM 自动调优,如果不满意,可以指定垃圾回收器。OutOfMemory 通常是由于堆内存不足,调节 -Xmx1024m 和 -XX:MaxPermSize=128m 命令行可选项即可。

IDEA 保姆级安装教程:  http://note.youdao.com/s/Wq2GSETJ  

计算机专业常用毕业设计集合:  http://note.youdao.com/s/PIJHOqnk  

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sqoop安装

文章目录 1. 上传安装包至虚拟机2. 解压安装包到指定路径3. 修改目录名4. 配置环境变量5. 修改配置文件6. 拷贝mysql驱动包7. 验证安装是否成功8. 测试sqoop连接mysql 注:sqoop安装的前提条件是环境已安装java和hadoop 1. 上传安装包至虚拟机 上传安装包sqoop-1.4.…

信通初试第一:无科研无竞赛一战上岸上海交大819学硕感悟

笔者来自通信考研小马哥23上交819全程班学员 信通初试第一:无科研无竞赛一战上岸上海交大819学硕感悟 原创2023-04-27 11:04通信考研小马哥 笔者来自通信考研小马哥23上交819全程班学员 本人情况: 本人是19届交本,本科成绩很差,…

赎金信(Hash的应用)

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 来源:力扣&#xff0…

Java 实现 YoloV7 目标检测

1 OpenCV 环境的准备 这个项目中需要用到 opencv 进行图片的读取与处理操作,因此我们需要先配置一下 opencv 在 java 中运行的配置。 首先前往 opencv 官网下载 opencv-4.6 :点此下载;下载好后仅选择路径后即可完成安装。 此时将 opencv\b…

WMS是什么?

WMS(Warehouse Management System)中文译作仓库管理系统,是一种专用于物流仓储管理的IT系统。它主要应用于企业物流中心、配送中心、供应商物料储备中心、电子商务配送中心等仓库管理过程中。 WMS系统可以帮助企业管理和控制其物流仓储流程。…

线程池的设计

一.什么是线程池? 线程池就是创建若干个可执行的线程放到容器中,有任务处理时,会提交到线程池中的任务队列中,线程处理完不是销毁,而是阻塞等待下一个任务。 二.为何要使用线程池? 降低资源消耗。重复利用创建好的线程减少线…

NLP原理和应用入门:paddle(梯度裁剪、ONNX协议、动态图转静态图、推理部署)

目录 一、梯度裁剪 1.1设定范围值裁剪 1. 全部参数裁剪(默认) 2. 部分参数裁剪 1.2 通过L2范数裁剪 1.3通过全局L2范数裁剪 二. 模型导出ONNX协议 三、动态图转静态图 3.1两种图定义 3.2 什么场景下需要动态图转静态图 3.3为什么动态图模式越来…

k8s 部署 seata1.6.0 集群 基于 nacos 注册中心 + mysql 数据库

k8s 部署 seata1.6.0 集群 基于 nacos 注册中心 mysql 数据库 大纲 1 镜像制作2 准备configmap3 准备deploy 部署文件4 部署seata到k8s 镜像制作 下载seata 选择1.6.0。下载后得到 seata-server-1.6.0.zip 已经上传到百度云盘 下载地址:http://seata.io/zh-cn…

Maven 依赖下载失败解决方案——配置国内源 + 具体解决办法

目录 前言 一、配置 Maven 国内源 二、重新下载jar包 三、其他问题 前言 最近发现 spring-boot 框架更新到 2.7.11 了,由于以前一直使用的是 2.7.9 ,所以一直出现依赖下载失败的问题,实际上这是由于 IDEA 会先加载之前下载好的依赖&#xf…

openharmony内核中不一样的双向链表

不一样的双向链表 链表初识别遍历双向链表参考链接 链表初识别 最近看openharmony的内核源码时看到一个有意思的双向链表,结构如下 typedef struct LOS_DL_LIST{struct LOS_DL_LIST *pstPrev; //前驱节点struct LOS_DL_LIST *pstNext; //后继节点 }LOS_DL_LIST;不…

FPGA入门系列12--RAM的使用

文章简介 本系列文章主要针对FPGA初学者编写,包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解,旨在更快速的提升初学者在FPGA开发方面的能力,每一个章节中都有针对性的代码…

Spring IOC DI - 整合MyBatis

Spring IOC目录 主要内容Spring 框架介绍Spring 框架的优势(对比以前项目的缺点)Spring 框架引入历史发展框架学习三要素Spring 模块介绍 Spring IoC/DI - 引入IoC/DI 概念辨析使用IoC/DI的好处IoC/DI具体应用场景 Spring IoC/DI - 代码实现环境准备Spring 框架环境搭建创建Mav…

图的遍历和应用

文章目录 图的遍历深度优先遍历对于无向图的邻接矩阵的深度优先遍历无向非连通图的深度优先遍历 对于无向图的邻接表的深度优先遍历非递归实现深度优先遍历无向图的邻接矩阵代码实现无向图的邻接表代码实现递归和非递归的同异 广度优先遍历邻接表BFS邻接矩阵BFS 图的应用生成树…

Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

前言 在项目研发中,相信大家都遇到过给用户增加头像照片的需求。 随着手机版本的不断更新,android 8、android 9、android 10、android 12、android 13、鸿蒙系统等等;遇到这个功能需求,大家肯定会想,“这还不好写&…

“双碳”目标下二氧化碳地质封存技术应用前景及模型构建实践方法

二氧化碳地质封存技术起步较晚,目前仍没有一套相对完整的行业规范;且就该技术而言,涉及环节众多,理论相对复杂,对于行业的新入局者不太友好。因此,结合时代背景,我们首次尝试对二氧化碳地质封存…

【裸金属服务器】安装VMware ESXi

官方安装操作ESXi地址 一、虚拟化服务器分类: 寄居架构(Hosted Architecture)和裸金属架构(Bare Metal Architecture)。 1、寄居架构(Hosted Architecture):在操作系统之上安装和运…

8.系统日志

1.api访问日志 对应数据库 拦截器 拦截逻辑 ApiAccessLogFilter类的createApiAccessLog方法 buildApiAccessLogDTO方法就是完善实体类,把接口执行时长之类的填充完整。 然后就是保存日志到infra_api_access_log数据库。 过滤器注册生效 2.api错误日志 对应数…

Windows 程序开机自启动速度优化,为什么腾讯会议自启动速度那么高?

目录 一、问题的说明和定义 二、问题的分析 1.问题初步分析 2.详细的分析: 2.1Windows常见的自启动方式 2.2Windows常见的自启动方式的细节分析 三、问题的解决方案 1、为什么腾讯会议Rooms那么快 2.我们是否可以跟腾讯会议一样快 一、问题的说明和定义 这…

Vue之插件的定义和使用

概述 学习本文之前,我们需要弄清楚何为插件?插件其实就是一段扩展程序,主要目的是用于扩展功能。就比如Idea家族和VSCode家族的插件,它们也是一段扩展程序,将其安装到IDE中就可以使用插件里面实现的功能了&#xff0c…

SCADA平台的HMI功能

01 前言 虹科Panorama SCADA平台支持桌面HMI、Web HMI和移动HMI的功能。桌面HMI主要是在桌面工作站实现数据可视化,能够获取到最全面的数据信息以及实现功能;Web HMI可以通过在软件中添加Web HMI服务器,运行程序后,可以在Web 客户…