当前位置: 首页 > news >正文

JVM之GC垃圾回收

GC垃圾回收

如何判断对象可以回收

  • 引用计数法

    如果有对象引用计数加一,没有对象引用,计数减一,如果计数为零,则回收

    但是如果存在循环引用,即A对象引用B对象,B对象引用A对象,会造成内存泄漏

  • 可达性分析算法

    1. java虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象

    2. 扫描堆中的对象,看是否能够沿着GC Root对象为起点的引用链找到该对象,找不到,表示可以回收

    3. 哪些对象可以作为GG Root?

      1. System Class

        例如:Object,String,HashMap等

      2. Native Stack

      3. Thread

      4. Busy Monitor

  • 四种引用

    • 强引用:new的对象,赋值的对象

      Object obj= new Object()//new 的对象都是是强引用
      

      只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了

    • 软引用

      Object obj= new Object()
      SoftReference sr = new SoftReference<>(obj);//obj就是软引用
      

      在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。

    • 弱引用

      Object obj= new Object()
      WeakReference wr = newWeakReference<>(obj);//obj就是软引用
      

      弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。在 JDK1.2 之后,用 java.lang.ref.WeakReference 来表示弱引用。

    • 虚引用

      Object obj= new Object()
      PhantomReference pr = new PhantomReference <>(obj);//obj就是软引用
      

      虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。

    • 终结器引用

      无需手动编码,但其内部配合引用队列使用,在垃圾回收时,终结器引用入队(被引用对象暂时没有被回收),再由Finalizer线程通过终结引用找到被引用对象并调用它的finalize方法,第二次GC时才能回收被引用的对象

垃圾回收算法

  • 标记清除

    标记:标记的过程其实就是,遍历所有的GC Roots,然后将所有GC Roots可达的对象标记为存活的对象。

    清除:清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。

    • 优点:速度快
    • 缺点:容易产生内存碎片
  • 标记整理

    标记:标记-整理算法从根对象开始遍历整个对象图,标记所有与根对象可达的对象,即被引用的对象。

    整理:标记-整理算法会对内存空间进行整理,将所有存活的对象移动到一端,而未标记的对象则被认为是垃圾对象。

    • 优点:没有产生"碎片"
    • 缺点:速度慢
  • 复制

    将活着的内存空间分为两块,每次只使用一块,在垃圾回收时将正在使用的内存块中的存活的对象复制到未被使用的内存块,之后清除正在使用的内存块中的所有对象,交换两块内存空间,完成垃圾回收

    • 优点:没有标记清除过程,运行高效,不会出现“碎片”问题
    • 缺点:需要两倍的内存空间

分代垃圾回收

在这里插入图片描述

老年代:存放长时间使用的对象

新生代:存放用完就可以丢弃的对象

  • MinorGC

    每次产生的新的对象在伊甸园区,如果进行了垃圾回收,那么会进行遍历所有对象,释放所有的的未被使用的对象,将使用的对象通过复制的方式,复制到幸存区S1,并进行年龄+1操作,表示该对象每次回收都没有被回收,当该值超过一个阈值时,就会将该对象放入老年代区,表示该对象可能会被长时间使用

    1. minor gc 会引发stop the world:进行垃圾回收时,会暂停其他的用户线程,等垃圾回收后,用户线程才恢复运行
    2. 当对象寿命超过阈值时,会晋升到老年区,最大寿命是15(4bit)
  • FullGC

    老年代空间都不足时,先触发Minorgc,如果之后内存空间仍然不足,则会触发FullGC,来对内存空间进行清理,STW(stop the world)的时间更长

相关VM的参数

在这里插入图片描述

大对象:如果说某个对象的大小超过了新生代内存大小,那么会将这个对象直接晋升到老年代内存块,不会发生GC回收

垃圾回收器

  • 串行

    1. 单线程的垃圾回收器

    2. 适用于堆内存较小的场景,个人电脑

    3. 打开串行垃圾回收器
      -XX:+UseSerialGC=Serial(新生代:复制算法) + SerialOld(老年代:标记整理算法)
      
    4. 在这里插入图片描述

  • 吞吐量优先(1.8默认的垃圾回收器)

    1. 多线程的垃圾回收器

    2. 适用于堆内存较大的场景,需要多核CPU的支持

    3. 让单位时间内STW的时间最短

    4. 在进行垃圾回收时会占满CPU

    5. 在这里插入图片描述

    6. -XX:parallelGCThreads=n //指定线程数量
      -XX:UseAdaptiveSizePolicy //采用自适应的大小调整策略,调整新生代的大小
      -XX:UseParallelGC //开启吞吐量优先垃圾回收器
      //ratio默认为99,此时值为0.01,只能由1%的时间用来进行垃圾回收(100min,只能有1min进行垃圾回收)
      -XX:GCTimeRatio=ratio //(公式:1/1+ratio)
      
  • 响应时间优先(基于标记清除算法)

    1. 多线程的垃圾回收器

    2. 适用于堆内存较大的场景,需要多核CPU的支持

    3. 尽可能的让单次STW的时间最短

    4. 在这里插入图片描述

    5. -XX:UseConcMarkSweepGC
      

G1(JDK9之后的默认的垃圾回收器)

定义:Garbage First

  1. 适用场景
  • 同时注重吞吐量和低延时,默认的暂时目标是200ms
  • 超大堆内存,会将堆划分为多个大小相等的Region
  • 整体上是标记+整理算法,两个区域之间是复制算法
  1. 相关参数
-XX:+UseG1GC
-XX:G1HeapRegionSize=size //设置Region的大小(1,2,4,8,16)
-XX:MaxGCPauseMillis=time //暂停目标时间
  1. G1垃圾回收阶段

    在这里插入图片描述

    3.1Young Collection(新生代)

    ​ 会STW

    ​ 会将幸存的对象,复制到幸存区,之后新生代内存满了,会将部分常用的对象复制到老年代内存

    3.2Young Collection+Concurrent Mark(新生代+并发标记)

    ​ 在YoungGC时会进行GC Root的初始标记

    ​ 老年代占用堆空间比例达到阈值时(默认为45%),进行并发标记(不会STW)

    3.3Mixed Collection(混合收集)

    ​ 会对伊甸园,新生区,老年区进行全面垃圾回收

    ​ 最终标记会STW

    ​ 拷贝存活会STW

  2. Young Collection 跨代引用

    新生代回收的跨代引用(老年代引用新生代)问题

垃圾回收调优

  1. 调优领域
    1. 内存
    2. 锁竞争
    3. cpu占用
    4. io
  2. 最快的GC是不发生GC
    1. 查看FullGC前后内存占用,考虑几个问题
      1. 是不是数据太多了
      2. 数据表示是否太臃肿
      3. 是否存在内存泄漏
  3. 新生代调优
    1. 所有new操作的内存分配非常廉价
    2. 死亡对象的回收代价为零
    3. 大部分对象用过即死
    4. minorgc时间远远低于fullgc
    5. 所以新生代内存块的大小应该设置为堆大小的1/4~1/2最佳,过大的话,会导致老年代内存过小,发生频繁 FullGC
    6. 幸存区要足够大到能保留当前活跃对象和需要晋升的对象
    7. 晋升阈值配置要得当,让长时间存活对象能尽快晋升
  4. 老年代调优(CMS)
    1. CMS的老年代内存越大越好
    2. 将老年代内存预设调至1/4~1/3

相关文章:

JVM之GC垃圾回收

GC垃圾回收 如何判断对象可以回收 引用计数法 如果有对象引用计数加一&#xff0c;没有对象引用&#xff0c;计数减一&#xff0c;如果计数为零&#xff0c;则回收 但是如果存在循环引用&#xff0c;即A对象引用B对象&#xff0c;B对象引用A对象&#xff0c;会造成内存泄漏 可…...

自然语言学习nlp 六

https://www.bilibili.com/video/BV1UG411p7zv?p118 Delta Tuning&#xff0c;尤其是在自然语言处理&#xff08;NLP&#xff09;和机器学习领域中&#xff0c;通常指的是对预训练模型进行微调的一种策略。这种策略不是直接更新整个预训练模型的权重&#xff0c;而是仅针对模型…...

fpga 需要掌握哪些基础知识?

个人根据自己的一些心得总结一下fpga 需要掌握的基础知识&#xff0c;希望对你有帮助。 1、数电&#xff08;必须掌握的基础&#xff09;&#xff0c;然后进阶学模电&#xff0c; 2、掌握HDL&#xff08;verilog或VHDL&#xff09;一般建议先学verilog&#xff0c;然后可以学…...

Qt未来市场洞察

跨平台开发&#xff1a;Qt作为一种跨平台的开发框架&#xff0c;具有良好的适应性和灵活性&#xff0c;未来将继续受到广泛应用。随着多设备和多平台应用的增加&#xff0c;Qt的前景在跨平台开发领域将更加广阔。 物联网应用&#xff1a;由于Qt对嵌入式系统和物联网应用的良好支…...

GPT-4模型中的token和Tokenization概念介绍

Token从字面意思上看是游戏代币&#xff0c;用在深度学习中的自然语言处理领域中时&#xff0c;代表着输入文字序列的“代币化”。那么海量语料中的文字序列&#xff0c;就可以转化为海量的代币&#xff0c;用来训练我们的模型。这样我们就能够理解“用于GPT-4训练的token数量大…...

宽字节注入漏洞原理以及修复方法

漏洞名称:宽字节注入 漏洞描述: 宽字节注入是相对于单字节注入而言的&#xff0c;该注入跟HTML页面编码无关&#xff0c;宽字节注入常见于mysql中&#xff0c;GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节&#xff0c;实际上只有两字节。宽字节带来的安全问…...

【Linux】SystemV IPC

进程间通信 一、SystemV 共享内存1. 共享内存原理2. 系统调用接口&#xff08;1&#xff09;创建共享内存&#xff08;2&#xff09;形成 key&#xff08;3&#xff09;测试接口&#xff08;4&#xff09;关联进程&#xff08;5&#xff09;取消关联&#xff08;6&#xff09;释…...

iview 页面中判断溢出才使用Tooltip组件

使用方法 <TextTooltip :content"contentValue"></TextTooltip> 给Tooltip再包装一下 <template><Tooltip transfer :content"content" :theme"theme" :disabled"!showTooltip" :max-width"300" :p…...

如何使用websocket

如何使用websocket 之前看到过一个面试题&#xff1a;吃饭点餐的小程序里&#xff0c;同一桌的用户点餐菜单如何做到的实时同步&#xff1f; 答案就是&#xff1a;使用websocket使数据变动时服务端实时推送消息给其他用户。 最近在我们自己的项目中我也遇到了类似问题&#xf…...

C++ 调用lua 脚本

需求&#xff1a; 使用Qt/C 调用 lua 脚本 扩展原有功能。 步骤&#xff1a; 1&#xff0c;工程中引入 头文件&#xff0c;库文件。lua二进制下载地址&#xff08;Lua Binaries&#xff09; 2&#xff0c; 调用脚本内函数。 这里调用lua 脚本中的process函数&#xff0c;并…...

Centos 内存和硬盘占用情况以及top作用

目录 只查看内存使用情况&#xff1a; 内存使用排序取前5个&#xff1a; 硬盘占用情况 定位占用空间最大目录 top查看cpu及内存使用信息 前言-与正文无关 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界中&…...

【数据结构】堆(创建,调整,插入,删除,运用)

目录 堆的概念&#xff1a; 堆的性质&#xff1a; 堆的存储方式&#xff1a; 堆的创建 &#xff1a; 堆的调整&#xff1a; 向下调整&#xff1a; 向上调整&#xff1a; 堆的创建&#xff1a; 建堆的时间复杂度&#xff1a; 向下调整&#xff1a; 向上调整&#xff…...

v-if 和v-for的联合规则及示例

第073个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使用&#xff0c;computed&a…...

各互联网企业测绘资质调研

公司子公司产品产品介绍资质获得资质时间阿里巴巴高德高德地图作为阿里的全资子公司&#xff0c;中国领先的数字地图内容、导航和位置服务解决方案提供商&#xff0c;互联网地图行业龙头&#xff0c;2021年4月高德实现全月平均日活跃用户数超过1亿的重要里程碑&#xff0c;稳居…...

C++自定义函数详解

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 铁汁们新年好呀&#xff0c;今天我们来了解自定义函数。 文章目录 1.数学中的函数 2.什么是自定义函数 3.自定义函数如何使用&#xff1f; 4.值传递和引用传递&#xff08;形参和实参区分&#xff09; …...

flask+vue+python跨区通勤人员健康体检预约管理系统

跨区通勤人员健康管理系统设计的目的是为用户提供体检项目等功能。 与其它应用程序相比&#xff0c;跨区通勤人员健康的设计主要面向于跨区通勤人员&#xff0c;旨在为管理员和用户提供一个跨区通勤人员健康管理系统。用户可以通过系统及时查看体检预约等。 跨区通勤人员健康管…...

Spring Boot动态加载Jar包与动态配置技术探究

Spring Boot动态加载Jar包与动态配置技术探究 1. 引言 在当今快节奏的软件开发领域&#xff0c;高效的开发框架是保持竞争力的关键。Spring Boot作为一款快速开发框架&#xff0c;以其简化配置、内嵌Web服务器、强大的开发工具等特性&#xff0c;成为众多开发者的首选。其背后…...

Lua metatable metamethod

示例代码 《programming in lua》里有一个案例很详细&#xff0c;就是写一个集合类的table&#xff0c;其负责筛选出table中不重复的元素并组合成一个新的table。本人按照自己的方式默写了一次&#xff0c;结果发现大差不差&#xff0c;代码如下&#xff1a; Set {} --集合--…...

HCIA-HarmonyOS设备开发认证V2.0-3.2.轻量系统内核基础-任务管理

目录 一、任务管理1.1、任务状态1.2、任务基本概念1.3、任务管理使用说明1.4、任务开发流程1.5、任务管理接口 一、任务管理 从系统角度看&#xff0c;任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源&#xff0c;并独立于其它任务运行。 O…...

中小型网络系统总体规划与设计方法

目录 1.基于网络的信息系统基本结构 2.网络需求调研与系统设计原则 3.网络用户调查 4.网络节点地理位置分布情况 5.网络需求详细分析 6.应用概要分析 7.网络工程设计总体目标与设计原则 8.网络结构与拓扑构型设计方法 9.核心层网络结构设计 10.接入核心路由器 11.汇聚…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...