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

Java如何判断堆区中的对象可以被回收了?

如何判断堆区中的对象可以被回收了


在Java中,垃圾回收机制会帮助我们自动回收不再被使用的对象,已到达即使释放内存的效果,但是Java又是怎么知道哪些对象不会再被我们继续使用了呢,希望你通过本篇文章,理解引用计数法与可达性分析法的运行方式

垃圾回收机制

在C/C++中,一个对象如果不再使用,就要手动将其释放掉,但是很多程序员在编写程序的时候经常忘记将一些对象回收,从而就导致了内存泄漏
在Java中为了简化对象的内存释放,引入了自动的垃圾回收机制,通过垃圾回收器把不再使用的对象完成自动回收,垃圾回收器主要负责堆上的内存回收,那么垃圾回收器又是如何知道哪些对象可以被回收了呢?

在Java中,一个对象是否可以被回收,主要是看这个对象是否被引用,如果对象被引用了,说明对象还在使用,是不可以被回收的,比如说如下代码中,堆内存中的Demo对象被demo引用,那么堆中的Demo对象就不会被回收:

public class Demo {public static void main(String[] args) {Demo demo = new Demo();}
}
栈内存
堆内存
main的栈帧
demo 引用
Demo对象

若此时将demo的引用设置为null:

demo = null;

那么此时Demo对象就处于了没有被引用的状态:

栈内存
main的栈帧
demo 引用
堆内存
Demo对象

此时Demo会被垃圾回收器进行回收,那么垃圾回收器又是怎么知道Demo对象目前没有被引用呢???


引用计数法

引用计数法会为每一个对象维护一个引用计数器,当对象被引用时加一,取消引用时减一,在上面的代码中,demo引用了堆上的Demo对象,所以Demo对象的引用计数器就加一,当把demo赋值为null的时候,也就是取消了Demo的引用,此时Demo对象引用计数器将减一成为0,此时垃圾回收器就认为Demo对象此时没有被任何引用,可以回收

栈内存
堆内存
main的栈帧
demo 引用
Demo对象
引用计数器:1

但是此时会出现一个问题,如果我new了两个对象A与B,并且A对象与B对象的互为彼此的成员变量,那么就会出现循环引用的现象,此时A对象被栈内存中的a1引用,也被B对象中的a变量引用,那么他的引用技术器应该为2:

public class Demo {public static void main(String[] args) {A a1 = new A();B b1 = new B();a1.b = b1;b1.a = a1;}
}
class A {B b;
}
class B {A a;
}
栈内存
堆内存
main的栈帧
A对象
B对象
a1
b1
a
B计数器:2
b
A计数器:2

那么此时,我取消a1、b1对A与B的引用

a1 = null;
b1 = null;

我们已经无法在程序中获取到A与B对象了,因为他们两个除了彼此间的引用关系,已经没有任何引用能够找到他们,所以按照常理来说,A与B对象都不会在程序中再使用了,理应被垃圾回收器进行回收,但是又由于存在彼此间的引用关系,引用计数器的值并不是0,那么此时垃圾回收器又会认为A与B都存在被引用的关系,所以并不会回收这两个类

栈内存
main的栈帧
a1
b1
堆内存
A对象
B对象
b
a
A计数器:1
B计数器:1

那么这种情况显然是不对的,无法回收的对象有可能会导致内存泄漏,所以Java并没有使用这种方法来判断类是否应该被回收,而是使用了另外一种方式


可达性分析法

Java使用的是可达性分析算法来判断对象是否可以被回收
可达性分析法将对象分为两类:

  • 垃圾回收根对象(GC Root)
  • 普通对象

对象与对象之间存在引用关系,形成一个引用链, 可达性分析算法就是指GC Root对象到某个对象间是可达的,即从GC Root对象开始,通过引用对象可以找到的对象爱国,即认为该对象还不能被回收

GC Root对象
普通对象
对象A
对象B
对象C
对象D

此时B、C、D对象都可以通过引用被GC Root对象找到,即他们都是可达的,所以不会被视为可回收的对象,但是如果对象A与对象B之间取消引用关系,那么即使对象C与对象D任然存在引用关系,但他们是不可达的,因此他们会被回收

GC Root对象
对象A
普通对象
对象B
对象C
对象D

Java虚拟机会持有一个所有GC Root对象的列表,用来判断哪些对象是不可达的,不可达的对象将被垃圾回收器进行回收:

再次回看上面的案例,如果使用可达性分析法,那么堆内存中应该存在一个GC Root对象引用了主线程里面mian方法的栈帧中的对象,此时如果a1与b1不再引用堆中的对象,那么就算A对象与B对象存在引用关系,但是他们是不可达的,就会被视为等待回收的对象:

堆内存
A对象
B对象
栈内存
main的栈帧
a1
b1
GC-Root对象
a
b

那么哪些对象可以被当中GC Root对象呢?
主要有四种GC Root对象:

  1. 线程Thread对象
    引用线程栈帧中的方法、参数、局部变量等等,上面我们的案例中就是线程Thread对象引用了mian方法栈帧中的a1与b1
  2. 类加载器加载到的java.lang.Class对象
    引用类中的静态变量
  3. 监视器对象
    用来保存同步锁synchronized关键字持有的对象
  4. 本地方法方法调用时使用的全局对象
    由Java虚拟机来控制调用

感谢您的阅读!文章到这里就结束了,如有错误,敬请指出。

  • 如果对你有帮助请点一个关注!
  • 希望能再次见到您!

相关文章:

Java如何判断堆区中的对象可以被回收了?

如何判断堆区中的对象可以被回收了 在Java中,垃圾回收机制会帮助我们自动回收不再被使用的对象,已到达即使释放内存的效果,但是Java又是怎么知道哪些对象不会再被我们继续使用了呢,希望你通过本篇文章,理解引用计数法与…...

.Net 6.0 监听Windows网络状态切换

上次发了一个文章获取windows网络状态&#xff0c;判断是否可以访问互联网。传送门&#xff1a;获取本机网络状态 这次我们监听网络状态切换&#xff0c;具体代码如下&#xff1a; public class WindowsNetworkHelper {private static Action<bool>? _NetworkStatusCh…...

UE4 材质学习笔记01(什么是着色器/PBR基础)

1.什么是shader 着色器是控制屏幕上每个像素颜色的代码&#xff0c;这些代码通常在图形处理器上运行。 现如今游戏引擎使用先进的基于物理的渲染和照明。而且照明模型模型大多数是被锁定的。 因此我们创建着色器可以控制颜色&#xff0c;法线&#xff0c;粗糙度&#xff0c;…...

算法 | 位运算(哈希思想)

位运算 &与两个位都为1时&#xff0c;结果才为1&#xff08;有0为0&#xff09;|或两个位都为0时&#xff0c;结果才为0&#xff08;有1为1&#xff09;^异或两个位相同为0&#xff0c;相异为1~取反0变1&#xff0c;1变0<<左移各二进位全部左移若干位&#xff0c;高…...

前端提升方向

1、脚手架配置&#xff1a;首先你会发现&#xff0c;一旦团队项目里多个项目之间的配置或者规范不同步&#xff0c;那么每个项目的配置都需要手动修改&#xff0c;而这很浪费时间。所以&#xff0c;你可以发起了一个团队的脚手架项目&#xff0c;把项目中的代码规范、Vite 配置…...

深度学习基础—残差网络ResNets

1.残差网络结构 当网络训练的很深很深的时候&#xff0c;效果是否会很好&#xff1f;在这篇论文中&#xff0c;作者给出了答案&#xff1a;Deep Residual Learning for Image Recognitionhttps://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_…...

鸿蒙ArkUI实战开发-主打自研语言及框架

ArkUI 是 HarmonyOS 的声明式 UI 开发框架&#xff0c;而 ArkUI-X 是基于 ArkUI 框架扩展而来的跨平台开发框架。ArkUI-X 支持 HarmonyOS、OpenHarmony、Android 和 iOS 平台&#xff0c;允许开发者使用一套代码构建支持多平台的应用程序。 一、ArkUI-X 的实战开发步骤 在实战开…...

HDU Sit sit sit (区间DP+组合数)

题目大意&#xff1a;有 n 张椅子&#xff0c;n 个人&#xff0c;所有人都可以按照任意顺序坐在任意一张椅子上&#xff0c;但是同时满足这三种情况的椅子不能坐&#xff1a; 1.椅子上有左右两张相邻的椅子。 2.左右相邻的椅子不是空的。 3.左右相邻的椅子颜色不同。 如果当前学…...

Qt开发技巧(十四)文字的分散对齐,设置动态库路径,进度条控件的文本,文件对话框的卡顿,滑块控件的进度颜色,停靠窗体的排列,拖拽事件的坑

继续讲一些Qt开发中的技巧操作&#xff1a; 1.文字的分散对齐 有时候需要对文本进行分散对齐显示&#xff0c;相当于无论文字多少&#xff0c;尽可能占满整个空间平摊占位宽度&#xff0c;但是在对支持对齐方式的控件比如QLabel调用 setAlignment(Qt::AlignJustify | Qt::Align…...

VirtulBOX Ubuntu22安装dpdk23.11

目录 依赖包安装 Python安装 numa安装 ​编辑Python pip3安装 ​编辑pyelftools安装 meson和ninja安装 ​编辑构建与编译 Meson构建DPDK ​编辑Ninja安装DPDK ​编辑VFIO-PCI驱动安装 大页内存和IOMMU配置 ​编辑VFIO-PCI加载 ​编辑VFIO-PCI驱动绑定 ​编辑dpdk…...

线性代数书中求解齐次线性方程组、非齐次线性方程组方法的特点和缺陷(附实例讲解)

目录 一、克拉默法则 1. 方法概述 2. 例16(1) P45 3. 特点 (1) 只适用于系数矩阵是方阵 (2) 只适用于行列式非零 (3) 只适用于唯一解的情况 (4) 只适用于非齐次线性方程组 二、逆矩阵 1. 方法概述 2. 例16(2) P45 3. 特点 (1) 只适用于系数矩阵必须是方阵且可逆 …...

初识算法 · 双指针(2)

目录 前言&#xff1a; 盛最多水的容器 题目解析&#xff1a; 算法原理&#xff1a; 算法编写&#xff1a; 有效三角形的个数 题目解析&#xff1a; 算法原理&#xff1a; 算法编写&#xff1a; 前言&#xff1a; 本文介绍两个题目&#xff0c;盛最多水的容器和有效三…...

React常见面试题目

React常见面试题目详解包括以下几个方面&#xff1a; 1. 对React的理解及特性 定义与用途&#xff1a;React是一个用于构建用户界面的JavaScript库&#xff0c;它遵循组件设计模式、声明式编程范式和函数式编程概念&#xff0c;使得前端应用程序更高效。 核心特性&#xff1a; …...

图解网络OSI模型与TCP/IP

一、OSI模型与TCP/IP 1、OSI模型 OSI/RM&#xff08;Open System Interconnection&#xff0c;开放系统互联参考模型&#xff09;是由ISO&#xff08;国际标准组织&#xff09;创建的一个有助于开放和理解计算机的通信模型&#xff0c;OSI七层参考模型作为一套规范的标准&…...

15分钟学 Python 第31天 :Web Scraping

Day 31&#xff1a;Web Scraping 1. Web Scraping 概述 Web Scraping&#xff08;网页抓取&#xff09;是一种自动提取网站数据的技术。它常用于从网页中收集信息&#xff0c;对数据进行分析和处理。无论是获取产品价格、市场调研&#xff0c;还是收集新闻信息&#xff0c;We…...

前端编程艺术(2)----CSS

目录 1.CSS 2.CSS引入 3.选择器 1.标签选择器 2.类选择器 3.id选择器 4.属性选择器 5.后代选择器 5.直接子元素选择器 6.伪类选择器 链接相关 动态伪类 结构化伪类 否定伪类 其他伪类 UI元素状态伪类 4.字体 1.font-family 2.font-size 3.font-style 4.fo…...

前端的全栈混合之路Meteor篇(二):RPC方法注册及调用

在Meteor 3.0中&#xff0c;RPC&#xff08;远程过程调用&#xff09;机制是实现前后端数据交互的重要特性。通过RPC&#xff0c;前端可以轻松调用后端方法&#xff08;Methods&#xff09;并获取数据&#xff0c;而后端的逻辑也可以同步或异步执行并返回结果。本文将详细介绍M…...

重学SpringBoot3-集成Redis(三)之注解缓存策略设置

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;三&#xff09;之注解缓存策略设置 1. 引入 Redis 依赖2. 配置 RedisCacheManager 及自定义过期策略2.1 示例代码&#xff1a;自定…...

【C++11】新特性

前言&#xff1a; C11 是C编程语言的一个重要版本&#xff0c;于2011年发布。它带来了数量可观的变化&#xff0c;包含约 140 个新特性&#xff0c;以及对 C03 标准中约600个缺陷的修正&#xff0c;更像是从 C98/03 中孕育出的新语言 列表初始化 C11 中的列表初始化&#xff0…...

【游戏模组】重返德军总部2009高清重置MOD,建模和材质全部重置,并且支持光追效果,游戏画质大提升

各位好&#xff0c;今天小编给大家带来一款新的高清重置MOD&#xff0c;本次高清重置的游戏叫《重返德军总部2009》2009年发布&#xff0c;我相信很多玩家已经玩过了&#xff0c;如果你还没有玩过我也可以和你简单介绍一下剧情&#xff0c;这款游戏故事背景接续在《重返德军总部…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...