先有JVM还是先有垃圾回收器?

是先有垃圾回收器再有JVM呢,还是先有JVM再有垃圾回收器呢?或者是先有垃圾回收再有JVM呢?历史上还真是垃圾回收更早面世,垃圾回收最早起源于1960年诞生的LISP语言,Java只是支持垃圾回收的其中一种。下面我们就来刨析刨析JVM的垃圾回收~

在这里插入图片描述

文章目录

    • 1. 判断可回收对象
      • 1.1 引用计数法
      • 1.2 可达性分析算法
    • 2. 垃圾回收器
      • 2.1 垃圾回收区域
      • 2.2 回收永久代
      • 2.3 垃圾回收器
      • 2.4 CMS原理
      • 2.5 CMS的缺点
      • 2.6 G1垃圾回收器
    • 3. 垃圾回收算法
      • 3.1 优化复制算法
    • 未完待续。。。

1. 判断可回收对象

1.1 引用计数法

面试官:JVM为什么不采用引用计数法?

每个Java对象在引用计数法里都有一个引用计数器,引用失效则计数器 - 1,有新的引用则计数器 + 1,通过计数器的数值来判断该对象是否是可回收对象。

大家看下这个例子,如果对象A和对象B没有被任何对象引用,也没有被任何线程访问,这两个对象按理应该被回收。但如果对象A的成员变量引用了对象B,对象B的成员变量引用了对象A,它们的引用计数器数值都不为0,通过引用计数法并不能将其视为垃圾对象。

    class A {B b = new B();}class B {A a = new A();}

就因为引用计数法很难解决对象之间相互循环引用的问题,所以目前JVM采用可达性分析算法来判断Java对象是否是可回收对象。

1.2 可达性分析算法

面试官:那你讲讲可达性分析算法?

可达性分析顾名思义就是以某个起始点来判断它是否可达,这个起始点称为GC Roots。如果Java对象不能从GC Roots作为起始点往下搜索到,那该对象就被视为垃圾对象,即可回收对象。

在这里插入图片描述

可以作为GC Roots对象一共包括以下四种,这点也是面试官常问的:

  1. 虚拟机栈中引用的对象。
  2. 本地方法栈中引用的对象。
  3. 方法区中类静态属性引用的对象。
  4. 方法区中常量引用的对象。

2. 垃圾回收器

2.1 垃圾回收区域

面试官:垃圾回收器回收的是哪个区域?

JVM由五大区域组成:堆内存、方法区、程序计数器、虚拟机栈、本地方法栈。先说结论,垃圾回收器回收的是堆内存和方法区两大区域。

程序计数器、虚拟机栈、本地方法栈的内存分配和回收都具备确定性,都是随着线程销毁而销毁,因此不需要进行回收

但在堆内存、方法区中,内存分配和回收都是动态的,我们只有在运行期间才能知道会创建哪些对象;另外这些垃圾对象不会自动销毁,如果任由这两部分区域的垃圾对象不管,势必造成内存的浪费甚至有内存泄漏的可能。

垃圾回收器存在的意义就是通过自动检测和回收这些垃圾对象,来减少内存泄漏的风险。

2.2 回收永久代

面试官:那永久代不会进行垃圾回收对吧?

虽然永久代的垃圾回收效率是比较低的,但永久代里的废弃常量和无用的类仍然会被回收。

例如创建一个字符串常量name,该字符串会存在于常量池中。如果该字符串没有任何String对象去引用它,当发生内存回收时有必要会清除该废弃常量。

private static final String name = "JavaGetOffer";

2.3 垃圾回收器

面试官:你说说都有哪些垃圾回收器?

目前市面上共有七种垃圾回收器。

  1. Serial是一个作用在新生代单线程垃圾回收器。在垃圾回收期间系统的所有线程都会阻塞,因此垃圾回收效率也相对较高

  2. ParNew则是Serial的多线程版本。这也是第一款并发的垃圾回收器,相比Serial来说垃圾回收不需要阻塞所有线程,第一次实现了让垃圾回收线程和用户线程同时工作。

  3. Serial Old是Serial的老年代版本。

  4. Parallel Scavenge同样是作用在新生代且是多线程,不过它的设计目标是达到一个可控制的吞吐量

  5. Parallel Old是Parallel Scavenge收集器的老年代版本,我们可以把它和Parallel Scavenge搭配一起使用。

  6. CMS是一种以最短停顿时间为目标的多线程收集器,下文我会介绍CMS实现最短停顿的原理。

  7. G1收集器可以说是CMS的升级版

我们可以根据业务实际情况来为各个年代搭配不同的垃圾回收器,以下的垃圾回收器如果有线连接,说明它们之间可以搭配使用。

在这里插入图片描述

2.4 CMS原理

面试官:你说的CMS为什么有较短的停顿?

CMS采用了标记-清除算法,整个运作过程分为了初始标记、并发标记、重新标记、并发清除四个阶段。

其中初始标记、重新标记的停顿时间是比较短的,而耗时最长的并发标记、并发清除能够和用户线程一起并发工作不需要停顿,可以说CMS只需要造成初始标记、重新标记带来的短时间停顿。

2.5 CMS的缺点

面试官:那它有什么缺点?

  1. CMS是多线程的,在垃圾回收时会占用一部分线程,可能会使系统变得相对较慢。
  2. CMS并发清理时用户线程还在运行着,也就是说还会有新的垃圾不断产生,这些垃圾被称为浮动垃圾。因为浮动垃圾产生在标记阶段后,很明显CMS本次收集是无法处理这些浮动垃圾的,只能等到下一次GC回收。
  3. CMS采用标记-清除算法,标记-清除算法的缺点是会产生空间碎片,有可能造成大对象找不到足够的连续空间而发生OOM的情况。

2.6 G1垃圾回收器

面试官:你说G1是CMS的升级版,为什么?

G1垃圾回收器设计之初被赋予的使命是未来可以替换掉JDK1.5中发布的CMS垃圾回收器。所以大家可想而知,CMS垃圾回收器的优点G1垃圾回收器都有,另外G1垃圾回收器也避免了CMS的一些不足。

  1. G1采用的垃圾回收算法是标记-整理算法,避免了CMS采用标记-清除可能产生的空间碎片。
  2. 其他收集器在新生代、老年代分别采用不同收集器进行配合,而G1垃圾回收器可以不需要其他收集器配合就能独立管理整个GC。

3. 垃圾回收算法

面试官:垃圾回收算法都有什么?

垃圾回收算法一共有四种,其中最基础的垃圾回收算法是标记-清除算法,其他算法其实都是对标记-清除算法的优化而产生的,我们继续往下看。

(1)标记-清除算法。

标记-清除算法顾名思义分为标记清除两个阶段,首先标记出所有可回收的对象,标记完成后统一进行清除。但该算法有一个缺点,被标记和未标记的对象都是分散存储在内存中的,当清除标记对象后会出现空间碎片的情况,如下图:

在这里插入图片描述

(2)复制算法。

复制算法把内存划分为容量相等的两块,每次只使用一块,当这一块内存不足时就将存活的对象复制到另一块中,同时清除当前块的内存空间。这种算法实现简单且运行高效,也不会产生空间碎片的情况,因为新生代的GC是比较频繁的,所以复制算法也广泛用于新生代的垃圾回收。但缺点很明显是浪费了50%的内存空间

(3)标记-整理算法。

标记-整理算法是对标记-清除算法的优化。该算法在内存到达一定量后,会把所有已标记的垃圾对象都向一端里移动,然后以存活对象所在的一端为边界,清除边界内所有内存,避免了标记-清除算法可能产生的空间碎片。

(4)分代收集算法。

一般实际业务系统都是采用分代收集算法。分代顾名思义把JVM内存拆分,分为了新生代、老年代,对不同年代的垃圾回收采用不同的垃圾回收算法来确保回收效率。

大家可以看下自己公司的JDK使用了什么垃圾回收器,加深下对本篇的理解。

# 打印JVM启动时的命令行标志
java -XX:+PrintCommandLineFlags -version

3.1 优化复制算法

面试官:复制算法可以怎么优化吗?

复制算法把内存划分为容量相等的两块,也就是按1:1分配内存,但这也浪费了50%空间

可以把内存分为一块较大的Eden空间和两块较小的Survivor空间,每次只使用Eden空间和其中一块Survivor空间,而另一块Survivor空间用来保存回收时还存活的对象。这样就只浪费了其中一块Survivor空间的内存。

覆盖Java程序员所需掌握的Java核心知识、面试重点,本博客收录在我开源的《Java学习面试指南》中,会一直完善下去,希望收到大家的 ⭐ Star ⭐支持,这是我创作的最大动力: https://github.com/hdgaadd/JavaGetOffer

未完待续。。。

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

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

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

相关文章

免费思维13招之十一:利润型思维

免费思维13招之十一:利润型思维 免费思维的另一大战略思维——利润型思维。 什么是利润型思维呢?就是用后期的利润来支付现在的成本。也就是“花未来的钱,办现在的事”。 我们在销售自己的产品时候,最容易犯的一个件事,就是降价,我们先来看一个案例: 前几年,有一个卖…

3dmax材质库导入方法?3dmax云渲染速度体验

3ds Max 材质库包含多种素材,如金属、木材、布料和石材等,但用户在导入材质时常遇到问题。本文将介绍如何在3ds Max中成功导入材质,并探讨使用云渲染服务来加速渲染过程,提高项目效率。 一、3dmax材质库导入教程 自建材质导入方法…

【js】获取媒体流实现拍照功能,摄像头切换

<script setup>import {onMounted,reactive,ref} from vueconst videoConstraints reactive({width: 500,height: 300});let picArr reactive([])let videoNode ref(null)let show ref(true)let stream reactive({})onMounted(async () > {// 获取视频流&#xf…

RuoYi-Vue-Plus (Logback 和 logback-plus.xml 、p6spy)

项目后本地日志 一、logback依赖 打开最外层的 pom.xml,查看 SpringBoot的依赖配置。 <dependencyManagement><dependencies><!-- SpringBoot的依赖配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>s…

position:fixed无法固定到父盒子上面的解决方案

目录 问题如图所示&#xff1a; 下面是错误的代码&#xff1a; 解决方案1&#xff1a; 使用fixed固定定位固定到父元素&#xff1a; 解决方案2&#xff1a; 推荐使用的其他方案&#xff08;粘性定位&#xff09;&#xff1a; 什么是粘性定位&#xff1a; 粘性定位的使用…

Leetcode—287. 寻找重复数【中等】(快慢指针算法)

2024每日刷题&#xff08;136&#xff09; Leetcode—287. 寻找重复数 快慢指针算法思想 low fast 时&#xff0c;快慢指针相遇&#xff0c;low 走过的距离是初始点&#xff08;0&#xff09;到环状开始的点 &#xff08;x&#xff09; 加上 环状开始的点&#xff08;x&…

LeetCode2390从字符串中移除星号

题目描述 给你一个包含若干星号 * 的字符串 s 。在一步操作中&#xff0c;你可以&#xff1a;选中 s 中的一个星号。移除星号 左侧 最近的那个 非星号 字符&#xff0c;并移除该星号自身。返回移除 所有 星号之后的字符串。注意&#xff1a;生成的输入保证总是可以执行题面中描…

详细分析Vue3中的ref(附Demo)

目录 前言1. 基本知识2. Demo 前言 由于新项目涉及Vue3&#xff0c;本着探究问题的本质研究所不会的疑问 1. 基本知识 ref 是 Vue 3 中用于创建响应式数据的函数 接收一个初始值并返回一个包含了该值的响应式引用对象与 Vue 2.x 中的 data 属性不同&#xff0c;ref 返回的是…

【已解决】力扣打不开

表现&#xff1a; 1.访问国内其他网站都没有问题 2.访问github也能成功 3.wifi没有问题 4.连接同网络的其他主机能打开 唯独力扣打不开&#xff0c;可能是DNS解析错误 》自己网络配置问题 解决办法【亲测可行】 找可用的hosts 打开站长之家&#xff0c;进行DNS查询&#xff…

卷积网络项目:实现识别鲜花四分类对比LeNet5、VGG16、ResNet18、ResNet34分类网络

卷积四分类项目 Gitee传送门 分类目标选取 鲜花 杏花 apricot_blossom桃花 peach_blossom梨花 pear_blossom梅花 plum_blossom 模型选择 卷积 LeNet5VGG16ResNet18ResNet34 以图搜图 获取相似度前10的搜图结果 数据清洗 鲜花四分类 删除非图片文件 删除重复图片 整理…

【JavaWeb】前后端分离SpringBoot项目快速排错指南

1 发起业务请求 打开浏览器开发者工具&#xff0c;同时显示网络&#xff08;Internet&#xff09;和控制台&#xff08;console&#xff09; 接着&#xff0c;清空控制台和网络的内容&#xff0c;如下图 然后&#xff0c;点击你的业务按钮&#xff0c;发起请求。 首先看控制台…

【C#进阶】简单数据结构类

简单数据结构类 文章目录 1、Arraylist1、ArrayList的本质2、声明3、增删查改4、装箱拆箱思考 背包售卖 2、Stack1、Stack的本质2、声明3、增取查改4、遍历思考 计算一个数的二进制 3、Queue1、Queue的本质2、声明3、增取查改4、遍历思考 每隔一段时间打印一条消息 4、Hashtab…

如何加密保护U盘?U盘加密方法盘点

U盘是目前最常用的移动存储设备&#xff0c;可以帮助我们存储大量数据。而为了保护数据安全&#xff0c;我们需要加密保护U盘。下面我们就来盘点一下U盘加密的方法。 BitLocker加密 BitLocker是Windows的一种磁盘保护工具&#xff0c;通过加密整个磁盘来保护数据&#xff0c;同…

基于Springboot的校园疫情防控信息管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园疫情防控信息管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层…

Vscode编辑器 js 输入log自动补全

最近换了新电脑&#xff0c;新下载了Vscode&#xff0c;记录一下设置项。 Vscode 版本 想要的效果 js文件中输入log&#xff08;点击tab键&#xff09;&#xff0c;自动补全为 console.log() Vscode 文件》首选项》设置 搜索&#xff1a;snippets Emmet: Show Suggestions…

暗区突围TWITCH掉宝领测试资格后,steam激活显示是无效激活码

自《暗区突围》测试启动以来&#xff0c;吸引了大量玩家关注&#xff0c;特别是通过在Twitch平台上观看直播即可获得测试资格的活动&#xff0c;更是掀起了热潮。然而&#xff0c;部分玩家在成功获得激活码后&#xff0c;在Steam平台激活时遭遇了“无效激活码”的问题。本文将提…

nginx 配置域名SSL证书HTTPS服务

下载 上传根目录 /home/wwwroot/xx.com/ssl 从新执行 添加域名命令 选择添加SSL SSL Certificate file: 填写 完整目录 PEM文件地址 SSL Certificate Key file:填写 完整目录 key文件地址

python 对矩阵与矩阵之间对应位置的元素,做softmax操作,代码实战

1.对矩阵中对应位置的元素&#xff0c;做softmax 对于一个向量&#xff0c;softmax函数会对其中每一个元素进行指数运算&#xff0c;然后除以所有元素指数和的结果。当将其应用到多个矩阵的相应位置上时&#xff0c;我们实际上是在对每个位置的一组数&#xff08;从各个矩阵的同…

45.WEB渗透测试-信息收集-域名、指纹收集(7)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;计算机王-CSDN博客 WEB指纹&#xff1a;Web指纹也叫web应用指纹。由于所使用的工具、技术…

PHP 自提时间

前端: 后台设置: 代码: public function getBusinessHour(){// 需求单门店$data (new StoreModel())->limit(1)->select()->toArray();$days explode(,, $data[0][shop_hours]);$businessHours $days[1];// 使用 explode 分割字符串&#xff0c;获取开始和结束时…