在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.hqwc.cn/news/215324.html

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

相关文章

[HCIE] IPSec-VPN (手工模式)

概念&#xff1a; A. IPSec&#xff1a;是对IP的安全性补充&#xff0c;工作在IP层&#xff0c;为IP网络通信提供安全服务。 B.安全联盟SA&#xff1a;是通信对等体之间对某些要素的协定。 C. IPSec安全联盟简称 IPSec SA.通常成对建立&#xff08;inbound和outbound&#x…

Oracle登录认证方式详解

文章目录 一、简介二、OS认证三、口令认证四、remote_login_passwordfile 详解 一、简介 在数据库管理中&#xff0c;登录认证是确保数据库安全性的重要环节。Oracle数据库提供 了两种认证方式&#xff0c;一种是“操作系统认证”&#xff0c;一种是“口令文件认证&#xff0c…

[chroot+seccomp逃逸] THUCTF2019 之 固若金汤

题目分析 附件为一个源码, 其中注释我都写好了, 主要就讲关键的知识点. #define _GNU_SOURCE#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include <sched.h> #include <uni…

2023年【山东省安全员C证】考试试卷及山东省安全员C证考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年【山东省安全员C证】考试试卷及山东省安全员C证考试试题&#xff0c;包含山东省安全员C证考试试卷答案和解析及山东省安全员C证考试试题练习。安全生产模拟考试一点通结合国家山东省安全员C证考试最新大纲及山东…

excel自己记录

1、清除换行符号 2、添加特殊符号&并清除换行符号 7日&15日&30日&60日 3、判断单元格最后一个字符是不是数字&#xff0c;不是就删掉 IF(ISNUMBER(--RIGHT(B2,1)),B2,SUBSTITUTE(B2,RIGHT(B2,1),"")) ISNUMBER(--RIGHT(B2,1))判断最右边的一个数是否…

【C语言】函数(四):函数递归与迭代,二者有什么区别

目录 前言递归定义递归的两个必要条件接受一个整型值&#xff08;无符号&#xff09;&#xff0c;按照顺序打印它的每一位使用函数不允许创建临时变量&#xff0c;求字符串“abcd”的长度求n的阶乘求第n个斐波那契数 迭代总结递归与迭代的主要区别用法不同结构不同时间开销不同…

DataFunSummit:2023年现代数据栈技术峰会-核心PPT资料下载

一、峰会简介 现代数据栈&#xff08;Modern Data Stack&#xff09;是一种集合了多种技术和工具的软件基础设施&#xff0c;旨在更好地管理和处理数据&#xff0c;并为企业提供数据驱动的洞察和决策。包含以下几个组件&#xff1a;数据采集、数据处理、数据存储、数据查询和分…

数据结构-归并排序+计数排序

1.归并排序 基本思想&#xff1a; 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有序&#xff0c;再使子序列段间有序。若将两个有序表合并成一个…

【电子通识】为什么说做产品不是简单的将不同的技术进行搭积木?

很多人说做产品的硬件工程师&#xff0c;其实就是将专项技术工程师已经调好的模块进行拼接。类似于小孩将积木搭成一个房子的形状&#xff0c;虽然不同人搭的房子风格迥异&#xff0c;但所使用的原材料却都是一样的。 首先我并不同意这种看法&#xff0c;原因是产品工程师是需要…

C语言之strstr函数的使用和模拟实现

C语言之strstr函数的模拟实现 文章目录 C语言之strstr函数的模拟实现1. strstr函数的介绍2. strstr函数的使用3. strstr的模拟实现3.1 实现思路3.2 实现代码 1. strstr函数的介绍 函数声明如下&#xff1a; char * strstr ( const char * str1, const char * str2 ); strs…

C#,《小白学程序》第二课:数组,循环与排序

1 什么是数组&#xff1f; 数组 Array 是一组数值&#xff08;数 或 值&#xff09;。 int[] a; int[,] b; int[][] c; Anything[] d; 都是数组。 2 排序 排序就是按大小、名字、拼音或你指定的信息进行比较后排队。 排序是数组最基本的功能需求。 3 文本格式 /// <summa…

游览器缓存讲解

浏览器缓存是指浏览器在本地存储已经请求过的资源的一种机制&#xff0c;以便在将来的请求中能够更快地获取这些资源&#xff0c;减少对服务器的请求&#xff0c;提高页面加载速度。浏览器缓存主要涉及到两个方面&#xff1a;缓存控制和缓存位置。 缓存控制 Expires 头&#…