JVM垃圾回收

文章目录

  • 垃圾回收
    • 四种引用
      • 引用计数算法
      • 可达性分析算法
    • 垃圾回收算法
      • 标记清除
      • 标记整理
      • 复制
    • 分代回收
    • GC
      • GC相关参数
      • GC分析
        • 大对象
    • 垃圾回收器
      • 串行
      • 吞吐量优先
      • 响应时间优先

垃圾回收

四种引用

  • 强引用
    new创建一个对象,通过等号运算符赋值给一个变量,那么这个变量就强引用了刚刚的对象
    只有所有GC Roots对象都不通过强引用引用该对象,该对象才能被垃圾回收
  • 软引用
    只要没被直接强引用所引用,都有可能被垃圾回收掉
    垃圾回收且内存不够时,且没有被强引用,就会将软引用的对象释放掉,认为软引用不重要
  • 弱引用
    只要没被直接强引用所引用,都有可能被垃圾回收掉
    垃圾回收时,不管内存够不够都会回收掉弱引用对象
  • 虚引用
    必须配合引用队列使用,主要配合ByteBuffer使用,被引用对象回收时,会将虚引用入队,由Reference Handler线程调用虚引用相关方法释放直接内存
  • 终结器引用
    必须配合引用队列使用,垃圾回收时,终结器入队,此时被引用对象暂时没有被回收,再由Finalizer线程通过终结器引用找到被引用对象并调用他的finalize方法,第二次GC时才能回收被引用对象

软弱引用还可以配合,引用队列使用,因为软引用,弱引用本身就是一个对象,当他们所引用对象被回收时,他们就会进入这个引用队列,因为他们自身也会占有一定内存,如果想对他们的内存进行释放,就需要引用队列

虚引用和终结器引用必须配合引用队列来使用,软弱引用可以不配合,虚终引用被创建时都会关联一个引用队列

如何判断对象可以回收

引用计数算法

在对象中添加一个引用计数器,当有地方引用时计数器就加一,引用失效时计数器减一,当计数器值为0时,进行回收

弊端:

当两对象再无引用,而这两对象循环引用时,引用计数都不为0,引用计数算法也无法回收他们

可达性分析算法

java通过该算法判断对象是否存活

思路:

通过一系列GC Root 作为根节点,再从这些根节点出发,根据引用关系向下搜索,走过的路称为引用链,如果某个对象没有任何一条引用链与之相连,那么这个对象是可以被回收的

哪些对象可以作为GC Root

  • 在虚拟机栈中引用的对象
  • 方法区中类静态属性引用的变量
  • 方法区中常量引用的对象,比如StringTable中的引用
  • 本地方法栈中JNI引用的对象
  • Java虚拟机内部的引用,如基本数据类型对应的Class对象,常驻的异常对象,还有类系统加载器
  • 被同步锁(synchronized)持有的对象
  • 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等

垃圾回收算法

JVM不会只用一种算法,会结合以下算法,协同工作,具体实现就是分代垃圾回收机制

标记清除

第一阶段对要垃圾回收的部分标记,第二阶段进行清除

  • 优点:速度快
  • 缺点:会产生内存碎片,造成内存空间的不连续

标记整理

  • 优点:没内存碎片
  • 缺点:速度慢

第一阶段对要垃圾回收的部分标记,第二阶段,在清除的过程中,会将可用的对象向前移动,让内存更紧凑,避免内存碎片问题

但是整理涉及到对象的移动,从而使效率较低

复制

  • 优点:没内存碎片
  • 缺点:需要占用双倍内存空间

在这里插入图片描述

分成两个区,FROM 和 TO,在FROM中对要回收的部分进行标记,再将可用的对象复制到TO中(TO区总是空着的)

再将from中内存清除,最后交换FROM和TO

分代回收

在这里插入图片描述

可以根据不同的内存区域,采用不同的垃圾回收策略,使垃圾回收更有效

  • 当创建了一个新的对象,默认是放在伊甸园区

  • 随着放在伊甸园的对象逐渐增多,伊甸园内存不足时,会触发Minor GC(会引发stop the world,暂停其他线程,垃圾回收结束后,其他线程恢复)

  • 采用可达性分析算法,将还可用的对象复制到幸存区TO中,并将幸存的对象的寿命+1,当幸存对象的寿命超过了15(不同的垃圾回收器阈值不一样),就会晋升到老年代中,释放伊甸园区剩余对象

  • 其中复制算法会将FROM和TO交换一次位置
    在这里插入图片描述

  • 再次创建对象,如果伊甸园区又满了,再次触发Minor GC,这时不仅会回收伊甸园垃圾,也会回收幸存区垃圾,再将可用对象(伊甸园区和幸存区from)复制到TO中,之后交换两个幸存区,并让幸存区中对象寿命+1

  • 当新生代和老年代内存都不足时,先尝试Minor GC,如果还不足,会触发Full GC(也会引发stop the world,时间更长)

GC

GC相关参数

含义	                          参数
堆初始大小					-Xms
堆最大大小					-Xmx-XX:MaxHeapSize=size
新生代大小					-Xmn(-XX:NewSize=size + -XX:MaxNewSize=size )
幸存区比例(动态)	 		 -XX:InitialSurvivorRatio=ratio 和 -XX:+UseAdaptiveSizePolicy
幸存区比例					-XX:SurvivorRatio=ratio
晋升阈值					 -XX:MaxTenuringThreshold=threshold
晋升详情				     -XX:+PrintTenuringDistribution
GC详情			  		  -XX:+PrintGCDetails -verbose:gc
FullGC前先做一次MinorGC	     XX:+ScavengeBeforeFullGC

GC分析

对JVM进行这样的设置

-Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc

当执行内容为空时

在这里插入图片描述

这里伊甸园区初始就有东西是因为Java程序启动时,需要加载一些类,这些类使用的就是伊甸园的区域

Metaspace是元空间

大对象

如果一个对象已经能够确定在新生代放不下,如果发现老年代能够容纳,就会直接晋升老年代

在这里插入图片描述

当老年代和新生代都不能容纳时,会抛出OOM(抛出前还会进行Full GC进行自救)

一个线程内的OOM不会导致其他线程也结束

垃圾回收器

  • 串行
    • 单线程
    • 适合堆内存较小,个人电脑
  • 吞吐量优先
    • 多线程
    • 适合堆内存较大,多核cpu(如果是单核的,那么多个线程就要去争抢cpu的时间片,效率还不如单线程)
    • 让单位时间内,STW时间最短
  • 响应时间优先
    • 多线程
    • 堆内存较大,多核cpu
    • 垃圾回收时,单次STW的时间尽可能短

串行

# 开启串行回收器
XX:+UseSerialGC = Serial + SerialOld

Serial收集器:
最基本的,历史最悠久的
单线程收集器,采用复制算法,工作在新生代
Serial Old收集器:
是Serial收集器的老年代版本
单线程,采用标记整理算法,工作在老年代

在这里插入图片描述

吞吐量优先

是JDK8默认使用的垃圾回收器

在这里插入图片描述

每次垃圾回收最大暂停毫秒数默认为200ms

要让垃圾回收最大暂停毫秒数变短,堆就得变小,而让吞吐量变大,即垃圾回收在总时间的占比减小,堆就得变大,所以这两个指标是相对的,需要折中选取

响应时间优先

ConcMarkSweepGC(CMS收集器):Concurrent Mark Sweep(并发,标记,清除)

  • 工作在老年代
  • 并发的:垃圾回收线程和用户线程同时执行(并行:垃圾回收线程和用户线程并行运行,但是在垃圾回收期间,用户线程不允许被执行)
  • 基于标记清除算法

ParNewGC:

  • 工作在新生代
  • 基于复制算法

在这里插入图片描述

  • 初始标记:标记GC Roots能直接到的对象,速度很快,存在STW
  • 并发标记:进行GC Roots Tracing过程,找出存活对象且用户线程可并发执行
  • 重新标记:修正并发标记期间因用户程序继续运行而导致标记产生变动的对象的标记记录,存在STW
  • 并发清理:对标记对象进行清理回收

因为是并发清理,所以在清理的过程中可能会产生其他垃圾(浮动垃圾),所以不能在堆内存不足时再做垃圾回收,需要预留些新空间,来保存浮动垃圾

所以-XX:CMSInitiatingOccupancyFraction=percent就是用来控制占用内存到总内存的百分之多少进行垃圾清理

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

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

相关文章

Vue3中的defineModel

目录 一、vue3的defineModel介绍 二、defineModel使用 (1)在vite.config.js中开启 (2)子组件 (3)父组件 一、vue3的defineModel介绍 为什么要使用到defineModel呢?这里有这样一种场景&…

Java设计模式分类

java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式(7种):适配器模式&am…

vue3中关于echars的使用

今天介绍一个好用的插件echars&#xff0c;一个可视化插件Apache ECharts 一、使用步骤 1、安装 npm install echarts --save 2、导入 import * as echarts from echarts 3、正式使用 echars的使用非常的简单&#xff0c;直接点击官网有现成的代码的可用 代码示例 <t…

【Spring教程24】Spring框架实战:从零开始学习SpringMVC 之 SpringMVC入门案例代码示例

目录 1:创建Maven项目&#xff0c;并导入对应的jar包2:创建控制器类3:创建配置类4:创建Tomcat的Servlet容器配置类5:配置Tomcat环境6:启动运行项目7:浏览器访问8:知识点总结 欢迎大家回到《Java教程之Spring30天快速入门》&#xff0c;本教程所有示例均基于Maven实现&#xff0…

FFmpeg抽取视频h264数据重定向

根据视频重定向技术解析中的 截获解码视频流的思路&#xff0c;首先需要解决如何输出视频码流的问题。 目前只针对h264码流进行获取&#xff0c;步骤如下&#xff1a; 打开mp4文件并创建一个空文件用于存储H264数据 提取一路视频流资源 循环读取流中所有的包(AVPacket),为…

2023团体程序设计天梯赛——模拟赛和总决赛题

M-L1-1 嫑废话上代码 Linux 之父 Linus Torvalds 的名言是&#xff1a;“Talk is cheap. Show me the code.”&#xff08;嫑废话&#xff0c;上代码&#xff09;。本题就请你直接在屏幕上输出这句话。 输入格式&#xff1a; 本题没有输入。 输出格式&#xff1a; 在一行中输出…

Docker Compose(容器编排)——9

目录 什么是 Docker Compose生活案例为什么要 Docker ComposeDocker Compose 的安装Docker Compose 的功能Docker Compose 使用场景Docker Compose 文件&#xff08;docker-compose.yml&#xff09; 文件语法版本文件基本结构及常见指令Docker Compose 命令清单 命令清单如下命…

【网络奇缘系列】计算机网络|数据通信方式|数据传输方式

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 这篇文章是关于计算机网络中数据通信的基础知识点&#xff0c; 从模型&#xff0c;术语再到数据通信方式&#…

C++面试宝典第4题:合并链表

题目 有一个链表&#xff0c;其节点声明如下&#xff1a; struct TNode {int nData;struct TNode *pNext;TNode(int x) : nData(x), pNext(NULL) {} }; 现给定两个按升序排列的单链表pA和pB&#xff0c;请编写一个函数&#xff0c;实现这两个单链表的合并。合并后&#xff0c;…

SqlServer中,数字-null的问题

一、业务描述 叫货单&#xff0c;已知叫货金额&#xff0c;填写本次付款金额&#xff0c;计算待付款金额 二、问题 在计算待付款金额时&#xff0c;偶尔会出现待付款金额为空的情况&#xff0c;百思不得其解 三、解决 仔细检查&#xff0c;发现了猫腻。 简单的说&#xff…

前端开发tips

前端开发tips 关于package.json里面&#xff0c;尖角号&#xff08;^&#xff09;和波浪线&#xff08;~&#xff09;的区别 在package.json里面&#xff0c;我们可以使用尖角号&#xff08;^&#xff09;和波浪线&#xff08;~&#xff09;来表示不同的包版本。这些符号通常被…

gin投票系统3

对应视频v1版本 1.优化登陆接口 将同步改为异步 原login前端代码&#xff1a; <!doctype html> <html lang"en"> <head><meta charset"utf-8"><title>香香编程-投票项目</title> </head> <body> <m…

[GPT]Andrej Karpathy微软Build大会GPT演讲(上)--GPT如何训练

前言 OpenAI的创始人之一,大神Andrej Karpthy刚在微软Build 2023开发者大会上做了专题演讲:State of GPT(GPT的现状)。 他详细介绍了如何从GPT基础模型一直训练出ChatGPT这样的助手模型(assistant model)。作者不曾在其他公开视频里看过类似的内容,这或许是OpenAI官方…

在javaweb项目中resource目录和webapp目录的区别

resource存放的是一些配置文件&#xff0c;这些文件一般都是与java代码相关的配置文件&#xff0c;比如这里的jdbc配置文件,在java中可以使用这个目录下的文件&#xff0c;不用写全路径 webapp存放的是web的资源文件&#xff0c;如jsp,html,css&#xff0c;js文件,在网页请求会…

〖大前端 - 基础入门三大核心之JS篇㊿〗- 面向对象之对象的方法、遍历、深浅克隆

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

基于Java Swing泡泡龙游戏(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

javaSwing酒店管理

一、介绍 在这篇博客中&#xff0c;我们将介绍一个基于MySQL数据库、Java编程语言和Swing图形用户界面的简单酒店管理系统。该系统包括了查询房客信息、查询房客状态、修改房客信息、添加房间信息、添加住户、退房管理、预定管理、退订管理、入账管理、出账管理、修改资料等多…

微信小程序制作-背单词的小程序制作

微信小程序–背单词的 好久没有发过文章了&#xff0c;但是不代表着我不去学习了喽&#xff0c;以下是我最近做的东西&#xff0c;前端的UI由朋友设计的&#xff0c;目前这个是前端使用的是微信小程序后端是Python的一个轻量型框架&#xff0c;FastApi&#xff0c;嗯&#xff…

fv悬浮球自定义任务正在编辑的文件操作失误丢失找回方法_fv悬浮球自定义任务推荐

场景&#xff1a;自定义任务时不小心点击了取消按钮或者删除按钮导致重要丢失 原因&#xff1a;因为fv悬浮球自定义任务没有撤回按钮 解决方案&#xff1a;使用系统的应用设置把悬浮球强制停止运行&#xff0c;默认&#xff08;开启全部权限&#xff09;然后它会自动重启&…

IBM Qiskit量子机器学习速成(六)

量子卷积神经网络 卷积和池化&#xff1a;卷积神经网络的必备成分 卷积神经网络被广泛应用于图像和音频的识别当中&#xff0c;关键在于“卷积”操作赋予神经网络统筹学习数据的能力。 执行卷积操作需要输入数据与卷积核&#xff0c;卷积核首先与输入数据左上角对齐&#xf…
最新文章