在JVM中 判定哪些对象是垃圾?

目录

垃圾的条件

1、引用计数法

2、可达性分析

3、强引用

4、软引用

5、弱引用

6、虚引用


判断垃圾的条件

在Java虚拟机(JVM)中,垃圾收集器负责管理内存,其中的垃圾收集算法用于确定哪些对象是垃圾,可以被回收以释放内存空间。Java中主要使用的是自动内存管理,垃圾收集器会自动识别和回收不再被程序引用的对象。以下是一些判定对象为垃圾的条件:

1、引用计数法

引用计数法是一种简单而直观的垃圾收集算法,其核心思想是通过在对象头中添加一个引用计数器,记录该对象被引用的次数。每当有一个新的引用指向该对象时,引用计数加一;当引用被删除或者超出作用范围时,引用计数减一。当引用计数为零时,表示该对象不再被引用,即可以被回收。

然而,引用计数法有一个明显的缺陷,即难以处理循环引用的情况。例如,两个对象互相引用,它们的引用计数永远不会变为零,即使它们已经不再被程序所使用。

以下是一个简单的引用计数法的Java代码示例:

class ReferenceCountingObject {private int referenceCount = 0;public ReferenceCountingObject() {// 对象初始化时,引用计数为 0}public void addReference() {referenceCount++;}public void removeReference() {referenceCount--;if (referenceCount == 0) {// 当引用计数为零时,可以进行垃圾回收操作System.out.println("对象被回收");}}
}public class ReferenceCountingExample {public static void main(String[] args) {// 创建两个对象ReferenceCountingObject obj1 = new ReferenceCountingObject();ReferenceCountingObject obj2 = new ReferenceCountingObject();// obj1 引用计数加一obj1.addReference();// obj2 引用计数加一obj2.addReference();// obj1 引用计数减一obj1.removeReference();// obj1 引用计数为零,可以进行垃圾回收// obj2 引用计数仍为一}
}

2、可达性分析

可达性分析是Java虚拟机中垃圾收集的核心算法之一,它主要通过判断对象是否能够从一组称为"GC Roots"的根对象出发,通过引用链追踪,最终判断对象是否可达。以下是关于可达性分析的一些详细细节和Java代码示例:

  1. GC Roots: GC Roots包括虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象以及本地方法栈中JNI(Java Native Interface)引用的对象。这些对象被认为是程序的根对象,是可达性分析的起始点。

  2. 可达性分析过程: 从GC Roots出发,通过对象引用链逐步追踪,判断对象是否能够被程序访问到。如果对象能够通过一系列引用到达GC Roots,则该对象被认为是可达的;反之,如果无法到达,则被认为是不可达的。

  3. 标记-清除算法: 在可达性分析过程中,标记-清除算法是一种常用的垃圾收集算法。通过标记可达的对象,然后清除不可达的对象,最终回收被标记的垃圾。

下面是一个简单的Java代码示例,演示了可达性分析的基本原理:

class MyClass {// 成员变量,作为引用private MyClass reference;public MyClass() {this.reference = null;}public void setReference(MyClass anotherObject) {this.reference = anotherObject;}
}public class ReachabilityAnalysisExample {public static void main(String[] args) {// 创建对象1MyClass obj1 = new MyClass();// 创建对象2MyClass obj2 = new MyClass();// obj1 的 reference 成员变量指向 obj2obj1.setReference(obj2);// obj2 的 reference 成员变量为空,不指向其他对象// 现在,obj1 和 obj2 都是可达的,因为它们可以通过引用链相互访问// 将 obj1 置为 null,切断对 obj1 的引用obj1 = null;// 现在,obj1 不可达,因为没有其他引用指向它,但 obj2 仍然可达// 执行垃圾回收System.gc();// 垃圾回收器可能会回收不可达的对象,释放其占用的内存// 在实际应用中,Java 虚拟机会根据不同的垃圾收集算法和策略执行垃圾回收}
}

 

3、强引用

强引用是最常见的引用类型,只要强引用存在,垃圾收集器就不会回收被引用的对象。当没有任何强引用指向一个对象时,该对象就变得不可达。

  • 特点: 强引用是最常见的引用类型,它会使对象始终保持存活。只要存在强引用指向一个对象,垃圾收集器就不会回收该对象。

  • 使用场景: 大多数对象的引用都是强引用,例如通过 new 操作符创建的对象就是强引用。当程序员希望确保对象不被垃圾收集器回收时,使用强引用是合适的。

Object obj = new Object(); // 强引用

 

4、软引用

软引用用于描述一些还有用但非必需的对象。在系统将要发生内存溢出之前,会尝试回收软引用指向的对象。

  • 特点: 软引用用于描述一些还有用但非必需的对象。当系统内存不足时,垃圾收集器会根据软引用的情况来决定是否回收该对象,以释放内存。

  • 使用场景: 软引用通常用于实现缓存策略,允许在内存不足时回收部分缓存而不会导致程序崩溃。

SoftReference<Object> softRef = new SoftReference<>(new Object());
Object obj = softRef.get(); // 获取软引用指向的对象

5、弱引用

弱引用也用于描述非必需对象,但它的生命周期比软引用更短。当垃圾收集器运行时,无论内存是否足够,都会回收被弱引用指向的对象。

  • 特点: 弱引用描述的是非必需对象,其生命周期比软引用更短。当垃圾收集器运行时,无论内存是否足够,都会回收被弱引用指向的对象。

  • 使用场景: 弱引用常用于实现对象缓存,但不希望缓存的对象影响垃圾回收。

WeakReference<Object> weakRef = new WeakReference<>(new Object());
Object obj = weakRef.get(); // 获取弱引用指向的对象

6、虚引用

虚引用是最弱的引用类型,几乎没有保持对象存活的作用。主要用于对象被回收前的一些清理操作。

  • 特点: 虚引用是最弱的引用类型,几乎没有保持对象存活的作用。主要用于对象被回收前的一些清理操作。虚引用必须和引用队列(ReferenceQueue)一起使用。

  • 使用场景: 虚引用主要用于跟踪对象被垃圾收集的状态,执行一些清理操作或者资源释放。

ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), referenceQueue);
// 虚引用不提供 get 方法,因为其并不保持对象的存活,需要通过 ReferenceQueue 来获取通知
Object obj = phantomRef.get(); // 返回始终为 null

 总体而言,这些引用类型在Java中提供了更灵活的内存管理手段,允许开发人员根据不同的场景来控制对象的生命周期。选择合适的引用类型取决于应用程序的需求,以及对内存使用和性能的权衡。

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

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

相关文章

VBA即用型代码手册之工作薄的关闭保存及创建

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

[Latex] Riemann 问题中的激波,接触间断,膨胀波的 Tikz 绘图

Latex 代码 \begin{figure}\begin{subfigure}[b]{0.32\textwidth}\centering\resizebox{\linewidth}{!}{\begin{tikzpicture}\coordinate (o) at (0,0);\coordinate (Si) at (2.5,2.5);\coordinate (x) at (1,0);\draw[->] (0,0) -- (3,0) node[right] {$x$};\draw[->] …

ArkTS-自定义组件学习

文章目录 创建自定义组件页面和自定义组件生命周期自定义组件和页面的区别页面生命周期(即被Entry修饰的组件)组件生命周期(即被Component修饰的组件) Builder装饰器&#xff1a;自定义构建函数按引用传递参数按值传递参数 BuilderParam装饰器&#xff1a;引用Builder函数 这个…

生物动力葡萄酒和有机葡萄酒一样吗?

农业维持了数十万年的文明&#xff0c;但当人类以错误的方式过多干预&#xff0c;过于专注于制造和操纵产品时&#xff0c;农业往往会失败。如果我们的目标是获得最高质量的收成&#xff0c;并长期坚持我们的做法&#xff0c;我们就必须与土地打交道。 当我们开始寻找生物动力…

应用内测分发平台如何上传应用包体?

●您可免费将您的应用&#xff08;支持苹果.ios安卓.apk文件&#xff09;上传至咕噜分发平台&#xff0c;我们将免费为应用生成下载信息&#xff0c;但咕噜分发将会对应用的下载次数进行收费&#xff08;每个账号都享有免费赠送的下载点数以及参加活动的赠送点数&#xff09;&a…

【电路笔记】-分压器

分压器 文章目录 分压器1、概述2、负载分压器3、分压器网络4、无功分压器4.1 电容分压器4.2 感应分压器 5、总结 有时&#xff0c;需要精确的电压值作为参考&#xff0c;或者仅在需要较少功率的电路的特定阶段之前需要。 分压器是解决此问题的一个简单方法&#xff0c;因为它们…

【Vue】filter的用法

上一篇&#xff1a; vue的指令 https://blog.csdn.net/m0_67930426/article/details/134599378?spm1001.2014.3001.5502 本篇所使用指令 v-for v-on v-html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…

记一次docker服务启动失败解决过程

环境&#xff1a;centos 7.6 报错&#xff1a;start request repeated too quickly for docker.service 由于服务器修复了内核漏洞&#xff0c;需要重启&#xff0c;没想到重启后&#xff0c;docker启动失败了 查看状态 systemctl status docker如下图 里面有一行提示&…

网络互联与IP地址

目录 网络互联概述网络的定义与分类网络的定义网络的分类 OSI模型和DoD模型网络拓扑结构总线型拓扑结构星型拓扑结构环型拓扑结构 传输介质同轴电缆双绞线光纤 介质访问控制方式CSMA/CD令牌 网络设备网卡集线器交换机路由器总结 IP地址A、B、C类IP地址特殊地址形式 子网与子网掩…

DCDC电感发热啸叫原因分析

一、电感发热啸叫原因解析 发热原因&#xff1a;电感饱和&#xff0c;实际使用的电感值<理论电感计算值 原因1&#xff1a;电感选择过小&#xff0c;计算值不合理。 原因2&#xff1a;PCB布局不合理&#xff0c;屏蔽型电感下方应设禁止铺铜区。 啸叫原因&#xff1a; 人耳的…

Log4j2.xml不生效:WARN StatusLogger Multiple logging implementations found:

背景 将 -Dlog4j.debug 添加到IDEA的类的启动配置中 运行上图代码&#xff0c;这里log4j2.xml控制的日志级别是info&#xff0c;很明显是没生效。 DEBUG StatusLogger org.slf4j.helpers.Log4jLoggerFactory is not on classpath. Good! DEBUG StatusLogger Using Shutdow…

Camera Raw v16.0.0(PS Raw增效工具)

Camera Raw 16是一款允许摄影师处理原始图像文件的软件PS增效工具。原始图像文件是未经相机内部软件处理的数码照片&#xff0c;因此包含相机传感器捕获的所有信息。Camera Raw 为摄影师提供了一种在将原始文件转换为更广泛兼容的格式&#xff08;如 JPEG 或 TIFF&#xff09;之…

搭建SRS视频服务器

去官方网站下载FFmpeg6.1 https://ffmpeg.org/download.html拷贝到CentOS7.9中的/opt目录下&#xff0c;解压并重命名 tar -xvf ffmpeg-6.1.tar.xz 解压后编译安装 ./configure make make install从github下载SRS4.0release 解压后 如果ffmpeg的路径不在/usr/local/bin/ffmpe…

【MATLAB】全网入门快、免费获取、持续更新的科研绘图教程系列2

14 【MATLAB】科研绘图第十四期表示散点分布的双柱状双Y轴统计图 %% 表示散点分布的双柱状双Y轴统计图%% Made by Lwcah &#xff08;公众号&#xff1a;Lwcah&#xff09; %% 公众号&#xff1a;Lwcah %% 知乎、B站、小红书、抖音同名账号:Lwcah&#xff0c;感谢关注~ %% 更多…

LeetCode二叉树小题目

Q1将有序数组转换为二叉搜索树 题目大致意思就是从一个数组建立平衡的二叉搜索树。由于数组以及进行了升序处理&#xff0c;我们只要考虑好怎么做到平衡的。平衡意味着左右子树的高度差不能大于1。由此我们可以想着是否能用类似二分递归来解决。 如果left>right,直接返回nul…

IO多路转接之epoll

目录 一. epoll的实现原理 二. epoll的相关接口 2.1 epoll_create -- 创建epoll模型 2.2 epoll_ctl -- 对epoll模型进行控制 2.3 epoll_wait -- 等待epoll所关注的事件就绪 2.4 epoll相关接口的使用方法 三. Epoll服务器的模拟实现 3.1 EpollServer类的声明 3.2 Epoll…

网工内推 | 美的、得力集团,包吃包住,IE认证优先,14薪

01 美的 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1.负责IT网络设备、IDC机房的日常维护巡检、监控和管理&#xff1b; 2.负责路由、交换、防火墙、无线控制器、AP等网络设备的开通、调整、优化升级&#xff1b; 3.负责公司OT、IT网络规划&#xff0c;项目实施以…

路由VRRP配置例子

拓朴如下&#xff1a; 主要配置如下&#xff1a; [R1] interface GigabitEthernet0/0/0ip address 10.1.1.1 255.255.255.0 vrrp vrid 1 virtual-ip 10.1.1.254vrrp vrid 1 priority 200vrrp vrid 1 preempt-mode timer delay 20 # interface GigabitEthernet0/0/1ip address …

【10套模拟】【10】

关键字&#xff1a; 线性探测次数、冒泡交换性质、排序次数最值、bst查找关键字最多比较次数、m叉树空指针域 链表合并、二叉排序树查找x、堆排序

css给盒子写四个角

如图&#xff1a;之前一直用定位 现在发现可以用css写 background: linear-gradient(to top, #306eef, #306eef) left top no-repeat, /*上左*/ linear-gradient(to right, #306eef, #386eef) left top no-repeat, /*左上*/ linear-gradient(to left, #386eef, #306eef) righ…