一文彻底搞懂Java对象什么时候被垃圾器回收

news2024/10/6 12:21:54

文章目录

  • 1. 简介
  • 2. 引用计数法
    • 2.1 优点
    • 2.2 缺点
  • 3. 可达性分析算法
    • 3.1 虚拟机栈(栈帧中的本地变量表)中引用的对象
    • 3.2 方法区中静态属性引用的对象
    • 3.3 方法区中常量引用的对象
    • 3.4 本地方法栈中 JNI(即一般说的 Native 方法)引用的对象

1. 简介

Java 是一门不需要自己手动控制内存释放的语言,有自动的垃圾回收机制,也就是我们熟悉的GC(Garbage Collection)。有了垃圾回收机制后,程序员只需要关心内存的申请即可,内存的释放由系统自动识别完成。

在进行垃圾回收时,不同的对象引用类型,GC会采用不同的回收时机,这时自动的垃圾回收的算法就会变得非常重要了,如果因为算法的不合理,导致内存资源一直没有释放,同样也可能会导致内存溢出的。

在这里插入图片描述

  • 如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收。
  • 如果要定位什么是垃圾,有两种方式来确定,第一个是引用计数法,第二个是可达性分析算法。

2. 引用计数法

主要思想是通过记录对象被引用的次数来判断对象是否可回收。当一个对象被创建时,引用计数加一;当一个引用指向该对象时,引用计数也加一;当引用失效或对象被销毁时,引用计数减一。当对象的引用计数变为零时,即表示该对象不再被任何引用指向,可以被垃圾收集器回收。

String demo = new String("123");

在这里插入图片描述

String demo = null;

在这里插入图片描述
JVM已经放弃了引用计数算法,这是因为当对象间出现了循环引用的话,则引用计数法就会失效。
在这里插入图片描述
虽然a和b都为null,但是由于a和b存在循环引用,这样a和b永远都不会被回收。

2.1 优点

  • 实时性:引用计数算法可以及时回收不再被引用的对象,无需等待特定的垃圾收集周期。
  • 简单高效:相对于其他垃圾收集算法,引用计数算法实现相对简单,在垃圾回收过程中,应用无需挂起。如果申请内存时,内存不足,则立刻报OOM错误。
  • 区域性:更新对象的计数器时,只是影响到该对象,不会扫描全部对象。

2.2 缺点

  • 循环引用问题:引用计数算法无法解决循环引用问题。即使对象之间相互引用,导致它们的引用计数都不为零,但实际上它们已经不再被外部引用,应该被回收。这种情况下,引用计数算法会导致内存泄漏。
  • 维护开销大:引用计数算法需要维护每个对象的引用计数,当对象被频繁引用和释放时,会增加计数器的操作开销。
  • 无法处理对象的相互引用:由于引用计数算法无法处理循环引用问题,因此无法处理对象之间的相互引用情况,容易导致内存泄漏。
  • 内存开销大:引用计数算法需要为每个对象维护一个额外的引用计数字段,增加了对象的内存开销。

3. 可达性分析算法

该算法会存在一个根对象【GC Roots】,递归地遍历所有可通过引用链访问到的对象,搜索过的路径被称为(Reference Chain),判断某对象是否与根对象有直接或间接的引用,如果没有被引用,则可以当做垃圾回收。现在JVM采用的都是通过可达性分析算法来确定哪些内容是垃圾。

在这里插入图片描述
X,Y这两个节点是可回收的,但是并不会马上的被回收。对象中存在一个方法finalize。当对象被标记为可回收后,当发生GC时,首先会判断这个对象是否执行了finalize方法,如果这个方法还没有被执行的话,那么就会先来执行这个方法,接着在这个方法执行中,可以设置当前这个对象与GC ROOTS产生关联,那么这个方法执行完成之后,GC会再次判断对象是否可达,如果仍然不可达,则会进行回收,如果可达了,则不会进行回收。
finalize方法对于每一个对象来说,只会执行一次。如果第一次执行这个方法的时候,设置了当前对象与RC ROOTS关联,那么这一次不会进行回收。 那么等到这个对象第二次被标记为可回收时,那么该对象的finalize方法就不会再次执行了。

根对象是那些肯定不能当做垃圾回收的对象,就可以当做根对象。在Java中,GC Roots包括四种:

  • 虚拟机栈中的引用对象
  • 方法区静态属性引用的对象
  • 方法区常量引用的对象
  • 本地方法栈JNI引用的对象

在这里插入图片描述

3.1 虚拟机栈(栈帧中的本地变量表)中引用的对象

/**
* demo是栈帧中的本地变量,当demo = null时,由于此时demo充当了GC Root的作用,
* demo与原来指向的实例new Demo()断开了连接,对象被回收。
*/
public class Demo {
public static void main(String[] args) {
Demo demo = new Demo();
demo = null;
}
}

3.2 方法区中静态属性引用的对象

/**
* 当栈帧中的本地变量b = null时,由于b原来指向的对象与GC Root (变量b) 断开了连接,
* 所以b原来指向的对象会被回收,而由于我们给a赋值了变量的引用,a在此时是类静态属性引用,
* 充当了 GC Root 的作用,它指向的对象依然存活!
*/
public class Demo {
public static Demo a;
public static void main(String[] args) {
Demo b = new Demo();
b.a = new Demo();
b = null;
}
}

3.3 方法区中常量引用的对象

/**
* 常量 a 指向的对象并不会因为 demo 指向的对象被回收而回收
*/
public class Demo {
public static final Demo a = new Demo();
public static void main(String[] args) {
Demo demo = new Demo();
demo = null;
}
}

3.4 本地方法栈中 JNI(即一般说的 Native 方法)引用的对象

任何 Native 接口都会使用某种本地方法栈,实现的本地方法是使用 C 连接模型的话,那么它的本地方法栈就是 C 栈。
当线程调用 Java 方法时,虚拟机会创建一个新的栈帧并压入 Java 栈,然而当它调用的是本地方法时,虚拟机会保持 Java 栈不变,虚拟机只是简单地动态连接并直接调用指定的本地方法。

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

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

相关文章

Day23--learning English

一、积累 1.straw 2.umami | tangy | bland 3.lactose dairy 4.fatigue 5.stumble | curb 6.pore 7.toll 8.arrear 9.robe 10.stylish 11.dash 12.mischief 13.ranch 14.sponsorship 15.podcast 16.villian 17.clutch 18.envision 二、练习 1.牛津原译 1.straw /strɔː/ 1…

ngnix网站服务详解

一 Nginx的简介 1 Nginx: ①Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热…

11 个适用于 Windows电脑的最佳免费录制屏幕软件(2024)

屏幕录制软件可让您捕获屏幕以与他人共享并创建与产品相关的视频、教程、课程、演示、网络视频等。该软件使您能够从网络摄像头和屏幕录制视频。 11 个适用于 Windows电脑的最佳免费屏幕录像机 以下是精心挑选的顶级屏幕录像机列表,及其受欢迎的功能和网站链接。该…

Spring Boot与Feign:微服务架构下的优雅通信

1. 前言 本文将详细介绍在Spring Boot框架中如何使用Feign进行微服务之间的优雅通信。我们将从Feign的基本原理讲起,然后逐步展开使用Feign的完整流程和步骤,包括代码示例和详细注释。通过本文,读者将能够轻松掌握Feign在Spring Boot微服务架…

为什么发明个红黑树,这么设计的意义是什么?

1、红黑树是一种自平衡二叉树,查找时算法时间复杂度为O(log n)。 2、 假设你计算机里存有十亿个身份证信息,你要用计算机在这些身份证信息里进行增加、删除、查找等操作,应该怎样设计程序实现这些功能? 最简单的笨办法&#xf…

基于JAVA的智慧社区业务综合平台 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 业务类型模块2.2 基础业务模块2.3 预约业务模块2.4 反馈管理模块2.5 社区新闻模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 业务类型表3.2.2 基础业务表3.2.3 预约业务表3.2.4 反馈表3.2.5 社区新闻表 四、系统展…

超详细shell脚本小练...

1 、判断当前磁盘剩余空间是否有30G,如果小于30G,则将报警邮件发送给管理员,每天检查-次磁盘剩余空间。 1.1.安装邮件服务 [rootnode ~]# df -m 文件系统 1M-块 已用 可用 已用% 挂载点 devtmpfs 7…

el-button 选择与非选择按钮批量处理

el-button 选择与非选择按钮批量处理 <el-button v-for"(voyage,i) in data[voyages][nowVoyage]":key"i"class"c-work-bts"type"primary":plain"nowWorkSpace!i"click"chooseWorkSpace(i)"size"small&qu…

week04day01(爬虫)

一. 爬虫 只爬取公开的信息&#xff0c;不能爬取未公开的后台数据 1.爬虫的合法性 法无禁止皆可为 -- 属于法律的灰色地带https://www.tencent.com/robots.txt -- 网站/robots.txt 可以查看禁止爬取的内容 2. URL Uniform Resource Locator 统一资源定位符https://www.…

小程序红包服务端请求一直是签名错误如何解决

当小程序红包服务端请求一直显示签名错误时&#xff0c;这可能是由于多种原因导致的&#xff0c;包括密钥错误、参数错误、签名算法错误、时间戳问题以及网络请求问题等。解决这个问题需要细心检查和分析&#xff0c;下面将简单的介绍一下如何针对这些可能的原因进行排查和解决…

获批上市:国产新一代长期型超小人工心脏

文章来源&#xff1a;心未来&#xff1b;编辑&#xff1a;白晓菲 近日&#xff0c;重庆永仁心医疗器械有限公司&#xff08;简称&#xff1a;"永仁心医疗"&#xff09;的新一代人工心脏产品EVA-Pulsar™左心室辅助装置正式获得NMPA医疗器械注册证&#xff0c;成为国…

【C语言】面试常考----- 内存函数memcpy和memmove的功能区别与模拟实现

1.memcpy 功能&#xff1a;把source指向的前num个字节内容拷贝到destination指向的位置去&#xff0c;可以拷贝任意类型的数据。 注&#xff1a;1.memcpy并不关心\0&#xff0c;毕竟传的也不一定是字符串&#xff0c;因此拷贝过程中遇到\0也不会停下来。 2.num的单位是字节&a…

(二十)springboot实战——springboot使用redis的订阅发布机制结合SSE实现站内信的功能

前言 在前面的章节内容中&#xff0c;我们介绍了如何使用springboot项目实现基于redis订阅发布机制实现消息的收发&#xff0c;同时也介绍了基于SSE机制的单通道消息推送案例&#xff0c;本节内容结合redis和sse实现一个常用的实战案例——站内信。实现系统消息的实时推送。 …

【C++】 类与对象——流操作符重载,const成员函数

类与对象 流操作符重载1 << 重载2 >> 重载 const 修饰Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇文章见&#xff01;&#xff01;&#xff01; 流操作符重载 流操作符功能<<输出操作符>>输…

2024 AI 大模型全栈开发知识体系【LLM 技术栈】

2023 年最火的一件事莫过于以 ChatGPT 为代表的 AI 大模型的兴起与应用探索&#xff0c;这一年大模型领域可以说是百花齐放&#xff0c;很多人都惊叹其在各行各业带来的影响。 有很多人说&#xff0c;AI 相对于当年的区块链、元宇宙有过之而无不及。 甚至于 2024 年 sora 的推出…

Python学习-列表1

十二、列表1 1、创建列表及基本运算 1&#xff09;使用中括号&#xff0c;将所有准备放入列表中的元素&#xff0c;包裹起来&#xff0c;不同元素之间使用逗号分隔。 举例&#xff1a; [1,2,3,4,5]2&#xff09;列表可以容纳不同类型的数据。 举例&#xff1a; [1,2,3,4,5,…

ETL快速拉取物流信息

我国作为世界第一的物流大国&#xff0c;但是在目前的物流信息系统还存在着几大的痛点。主要包括以下几个方面&#xff1a; 数据孤岛&#xff1a;有些物流企业各个部门之间的数据标准不一致&#xff0c;难以实现数据共享和协同&#xff0c;容易导致信息孤岛。 操作繁琐&#x…

【论文阅读】【yolo系列】YOLO-Pose的论文阅读

Abstract 我们介绍YOLO-pose&#xff0c;一种无热图联合检测的新方法&#xff0c;基于流行的YOLO目标检测框架的图像二维多人姿态估计。 【现有方法的问题】现有的基于热图的两阶段方法是次优的&#xff0c;因为它们不是端到端可训练的&#xff0c;训练依赖于surrogate L1 loss…

常用的消息中间件RabbitMQ

目录 一、消息中间件 1、简介 2、作用 3、两种模式 1、P2P模式 2、Pub/Sub模式 4、常用中间件介绍与对比 1、Kafka 2、RabbitMQ 3、RocketMQ RabbitMQ和Kafka的区别 二、RabbiMQ集群 RabbiMQ特点 RabbitMQ模式⼤概分为以下三种: 集群中的基本概念&#xff1a; 集…

unity学习(19)——客户端与服务器合力完成注册功能(1)入门准备

逆向服务器用了三天的时间&#xff0c;但此时觉得一切都值&#xff0c;又可以继续学习了。 服务器中登录请求和注册请求由command变量进行区分&#xff0c;上一层的type变量都是login。 public void process(Session session, SocketModel model) {switch (model.Command){ca…