JVM---对象是否存活及被引用的状态

1.如何判断对象是否存活

1.1 引用计数算法

        概念:在对象头部增加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。

        优点:速度快,高效

        缺点: 假如此时A引用B,B引用A那么,计数永远不为0,那么永远无法回收他们

1.2 可达性分析算法:

        概念:通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连,或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。

       总结概念: 也就是找到是否连接根节点,此时如果A引用B,B引用A就不会发生,循环回收不掉的问题,因为他们找不到连接的根节点,也是当前主流的判断对象是否存活的算法

        注意:即使在可达性分析算法中判定为不可达的对象,也不是“非死不可”的,这时候它们暂时还处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记,随后进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。

2.再谈引用

        无论是通过引用计数算法判断对象的引用数量,还是通过可达性分析算法判断对象是否引用链可 达,判定对象是否存活都和“ 引用 离不开关系。
        在JDK 1.2 版之前, Java 里面的引用是很传统的定义: 如果reference 类型的数据中存储的数值代表的是另外一块内存的起始地址,就称该 reference 数据是代表 某块内存、某个对象的引用。这种定义并没有什么不对,只是现在看来有些过于狭隘了,一个对象在 这种定义下只有“ 被引用 或者 未被引用 两种状态,对于描述一些 食之无味,弃之可惜 的对象就显 得无能为力。
        譬如我们希望能描述一类对象:当内存空间还足够时,能保留在内存之中,如果内存空
间在进行垃圾收集后仍然非常紧张,那就可以抛弃这些对象 —— 很多系统的缓存功能都符合这样的应用场景。
        所以在JDK 1.2版之后,Java对引用的概念进行了扩充,引入了四种引用

3.四种引用

2.1  强引用

        是最传统的“引用”的定义,是指在程序代码之中普遍存在的引用赋值,即类似“Object obj=new Object()”这种引用关系。无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。

2.2 软引用

        是用来描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。在JDK 1.2版之后提供了SoftReference类来实现软引用。

2.3 弱引用

        也是用来描述那些非必须对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生为止。当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK 1.2版之后提供了WeakReference类来实现弱引用。

2.4 虚引用

        也称为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2版之后提供了PhantomReference类来实现虚引用。

3. 软引用的进一步了解

3.1 软引用的使用场景

         软引用主要用于实现内存敏感的高速缓存。当系统内存充足时,软引用的对象可以长时间驻留在内存中,供程序快速访问;当系统内存不足时,这些对象可以被垃圾回收器回收,从而避免内存溢出错误。这种机制非常适合用于缓存系统,如图片缓存、页面缓存等。

3.2 为什么用到了软引用

  1. 内存压力下的灵活应对:软引用允许JVM在内存紧张时自动回收对象,从而避免了程序因为内存不足而崩溃的风险。

  2. 提高性能:通过保留软引用对象,在内存充足时可以直接访问这些对象,减少了重新加载或重新计算这些对象所需的时间和资源。

  3. 资源管理的灵活性:开发者可以通过软引用来控制缓存的大小和生命周期,而不是完全依赖于JVM的垃圾回收机制。

3.3 软引用的使用(小例子)

import java.lang.ref.SoftReference;  
  
public class SoftReferenceExample {  
    public static void main(String[] args) {  
        // 假设这是我们需要缓存的数据  
        Object data = new Object();  
  
        // 创建一个软引用指向这个数据  
        SoftReference<Object> softRef = new SoftReference<>(data);  
  
        // 使用softRef.get()来获取软引用指向的对象  
        Object cachedData = softRef.get();  
  
        // 模拟内存紧张的情况(实际上在简单示例中无法直接模拟)  
        // 在实际环境中,当JVM进行垃圾回收时,如果内存不足,可能会回收softRef指向的对象  
  
        // 再次尝试获取对象,如果对象已被回收,则返回null  
        cachedData = softRef.get();  
        if (cachedData != null) {  
            // 对象仍然存在,可以继续使用  
        } else {  
            // 对象已被回收,需要重新加载或重新计算  
        }  
    }  
}

注意:由于垃圾回收的时机和过程是由JVM的垃圾回收器控制的,因此我们不能精确地预测软引用对象何时会被回收。在实际应用中,开发者需要根据应用的内存需求和性能要求来合理使用软引用。

4. 弱引用的进一步了解

4.1 使用场景

  1. 缓存系统
    • 在一些缓存系统中,特别是当缓存的数据量很大且不是必需时,可以使用弱引用来引用这些数据。这样,当JVM内存不足时,这些数据可以被自动回收,从而避免内存溢出。
    • 例如,WeakHashMap就是基于弱引用实现的,它允许键值对中的键是弱引用的。这意味着,如果某个键除了被WeakHashMap所引用外,没有其他强引用指向它,那么这个键以及它所对应的值都可能被垃圾回收器回收。
  2. 生命周期较短的临时对象
    • 对于那些生命周期较短,且对内存敏感的临时对象,可以使用弱引用来引用它们。这样,一旦这些对象不再被其他强引用所指向,它们就可以被垃圾回收器及时回收。

4.2 为什么用到了弱引用

  1. 内存管理的灵活性
    • 弱引用提供了一种比软引用更加灵活的内存管理方式。通过弱引用,开发者可以更加精确地控制对象的生命周期,避免内存泄漏,同时也能够确保在内存不足时能够自动回收非必需的对象。
  2. 减少内存泄漏的风险
    • 在一些复杂的应用程序中,由于对象之间的引用关系错综复杂,很容易出现内存泄漏的情况。通过使用弱引用,可以减少因为对象之间的强引用关系而导致的内存泄漏风险。
  3. 提升性能
    • 在一些性能敏感的应用程序中,及时回收不再使用的对象可以释放更多的内存空间,从而提升应用程序的性能。弱引用通过自动回收非必需的对象,有助于减少内存占用,提升性能。

4.3 弱引用的使用(小例子)

import java.lang.ref.WeakReference;  
  
public class WeakReferenceExample {  
    public static void main(String[] args) {  
        // 创建一个强引用对象  
        Object strongRef = new Object();  
  
        // 创建一个弱引用对象,指向强引用对象  
        WeakReference<Object> weakRef = new WeakReference<>(strongRef);  
  
        // 验证弱引用是否有效  
        System.out.println(weakRef.get()); // 输出对象地址  
  
        // 将强引用置为null,模拟对象不再被强引用  
        strongRef = null;  
  
        // 触发垃圾回收(注意:实际环境中,垃圾回收的时机是不确定的)  
        System.gc();  
  
        // 再次验证弱引用是否有效  
        // 由于强引用已被置为null,且没有其他强引用指向该对象,因此该对象可能会被垃圾回收  
        // 此时,weakRef.get()可能返回null  
        System.out.println(weakRef.get()); // 可能输出null  
    }  
}

同样和弱引用相同:由于垃圾回收的时机和过程是由JVM的垃圾回收器控制的,因此我们不能精确地预测弱引用对象何时会被回收。在实际应用中,开发者需要根据应用的内存需求和性能要求来合理使用弱引用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW学习-LabVIEW储存Excel表格

上述实现了将格式化的时间和正弦波的频率振幅相位以及正弦波数据输入到excel表格中。 下面介绍其中使用到的函数&#xff1a; 1. 所在位置&#xff0c;函数选板->定时->获取日期/时间(秒) 2. 将获取的时间进行格式化处理&#xff0c;输出格式化的日期/时间字符串。 函…

AI赋能基础设施巡检,技术革新助力水泥建筑缺陷检测分析,基于YOLOv8模型开发构建水泥建筑场景下裂缝缺陷分割检测识别系统

在现代化城市建设的宏伟蓝图中&#xff0c;公路、隧道、桥梁、大坝等水泥类基础设施如同城市的血脉&#xff0c;支撑着社会的正常运转与经济的蓬勃发展。然而&#xff0c;时间的侵蚀与自然的考验使得这些建筑不可避免地面临老化与损坏的问题&#xff0c;裂缝作为其中最为常见的…

AV1 编码标准环路滤波和后处理技术概述

AV1 环路滤波 去块滤波器 在视频编码的环路滤波管道中&#xff0c;去块滤波器&#xff08;deblocking filter&#xff09;用于减少量化引起的变换块边界处的块状伪影。 总结&#xff1a; 去块滤波器的应用&#xff1a; 对于亮度&#xff08;luma&#xff09;色度分量&#xff…

minIO集成springboot

问题 minIO与spring集成。 步骤 创建桶 创建key 找到创建账号页面&#xff0c;如下图&#xff1a; 点击创建&#xff0c;如下图&#xff1a; 设置如下权限&#xff1a; {"Version": "2012-10-17","Statement": [{"Effect": &q…

华为OD算法题汇总

60、计算网络信号 题目 网络信号经过传递会逐层衰减&#xff0c;且遇到阻隔物无法直接穿透&#xff0c;在此情况下需要计算某个位置的网络信号值。注意:网络信号可以绕过阻隔物 array[m][n]&#xff0c;二维数组代表网格地图 array[i][j]0&#xff0c;代表i行j列是空旷位置 a…

如何在所有docker命令前加上一个sudo

如果当前登录用户不是root不用&#xff0c;使用docker命令的时候&#xff0c;需要在前面加上一个sudo 提升权限。 但是每次都加&#xff0c;就感觉特别的麻烦&#xff0c;如何简化呢&#xff1f; 解决办法 打开你的shell配置文件&#xff08;例如&#xff0c;如果你使用bash&am…

Spring Cloud Eureka快读入门Demo

1.什么是Eureka&#xff1f; Eureka 由 Netflix 开发&#xff0c;是一种基于REST&#xff08;Representational State Transfer&#xff09;的服务&#xff0c;用于定位服务&#xff08;服务注册与发现&#xff09;&#xff0c;以实现中间层服务的负载均衡和故障转移&#xff…

C语言 | Leetcode C语言题解之第239题滑动窗口最大值

题目&#xff1a; 题解&#xff1a; int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize) {int prefixMax[numsSize], suffixMax[numsSize];for (int i 0; i < numsSize; i) {if (i % k 0) {prefixMax[i] nums[i];} else {prefixMax[i] fmax(pref…

甄选范文“论软件维护方法及其应用”软考高级论文,系统架构设计师论文

论文真题 软件维护是指在软件交付使用后,直至软件被淘汰的整个时间范围内,为了改正错误或满足 新的需求而修改软件的活动。在软件系统运行过程中,软件需要维护的原因是多种多样的, 根据维护的原因不同,可以将软件维护分为改正性维护、适应性维护、完善性维护和预防性 维护…

Mindspore框架CycleGAN模型实现图像风格迁移|(三)损失函数计算

Mindspore框架&#xff1a;CycleGAN模型实现图像风格迁移算法 Mindspore框架CycleGAN模型实现图像风格迁移|&#xff08;一&#xff09;CycleGAN神经网络模型构建 Mindspore框架CycleGAN模型实现图像风格迁移|&#xff08;二&#xff09;实例数据集&#xff08;苹果2橘子&…

JAVA 异步编程(异步,线程,线程池)一

目录 1.概念 1.1 线程和进程的区别 1.2 线程的五种状态 1.3 单线程,多线程,线程池 1.4 异步与多线程的概念 2. 实现异步的方式 2.1 方式1 裸线程&#xff08;Thread&#xff09; 2.1 方式2 线程池&#xff08;Executor&#xff09; 2.1.1 源码分析 2.1.2 线程池创建…

新的“SCALE”软件允许为 AMD GPU 原生编译 CUDA 应用程序

虽然已经有各种努力&#xff0c;如HIPIFY来帮助将CUDA源代码转换为AMD GPU的可移植C代码&#xff0c;然后是之前AMD资助的ZLUDA&#xff0c;允许CUDA二进制文件通过CUDA库的直接替代品在AMD GPU上运行&#xff0c;但有一个新的竞争者&#xff1a;SCALE。SCALE现在作为GPGPU工具…

超算网络体系架构-资源层-平台层-服务层-应用层

目录 超算网络体系架构 我国超算基础设施 超算互联网相关标准研制方面 技术架构 资源层 基础资源 芯片多样 体系异构 高效存储 高速互连 资源池化 可隔离 可计量 互联网络 高带宽 低时延 高安全 平台层 算力接入 资源管理 算力调度 用户管理 交易管理 模…

基于springboot和mybatis的RealWorld后端项目实战二之实现tag接口

修改pom.xml 新增tag数据表 SET FOREIGN_KEY_CHECKS0;-- ---------------------------- -- Table structure for tags -- ---------------------------- DROP TABLE IF EXISTS tags; CREATE TABLE tags (id bigint(20) NOT NULL AUTO_INCREMENT,name varchar(255) NOT NULL,PR…

VBA学习(21):遍历文件夹(和子文件夹)中的文件

很多时候&#xff0c;我们都想要遍历文件夹中的每个文件&#xff0c;例如在工作表中列出所有文件名、对每个文件进行修改。VBA给我们提供了一些方式&#xff1a;&#xff08;1&#xff09;Dir函数&#xff1b;&#xff08;2&#xff09;File System Object。 使用Dir函数 Dir…

2024年大数据高频面试题(中篇)

文章目录 Kafka为什么要用消息队列为什么选择了kafkakafka的组件与作用(架构)kafka为什么要分区Kafka生产者分区策略kafka的数据可靠性怎么保证ack应答机制(可问:造成数据重复和丢失的相关问题)副本数据同步策略ISRkafka的副本机制kafka的消费分区分配策略Range分区分配策略…

三级域名能申请SSL证书吗?

在当今互联网时代&#xff0c;SSL证书已经成为了保障网站安全的重要工具&#xff0c;企业会为网站部署SSL证书来实现HTTPS加密以保护传输数据安全。然而随着业务的增长以及交易规模的扩大&#xff0c;为了更好的管理业务和内容&#xff0c;企业会在主域名的基础上划分二级域名&…

GitHub 令牌泄漏, Python 核心资源库面临潜在攻击

TheHackerNews网站消息&#xff0c;软件供应链安全公司 JFrog 的网络安全研究人员称&#xff0c;他们发现了一个意外泄露的 GitHub 令牌&#xff0c;可授予 Python 语言 GitHub 存储库、Python 软件包索引&#xff08;PyPI&#xff09;和 Python 软件基金会&#xff08;PSF&…

【RabbitMQ】一文详解消息可靠性

目录&#xff1a; 1.前言 2.生产者 3.数据持久化 4.消费者 5.死信队列 1.前言 RabbitMQ 是一款高性能、高可靠性的消息中间件&#xff0c;广泛应用于分布式系统中。它允许系统中的各个模块进行异步通信&#xff0c;提供了高度的灵活性和可伸缩性。然而&#xff0c;这种通…

网络准入控制设备是什么?有哪些?网络准入设备臻品优选

小李&#xff1a;“小张&#xff0c;最近公司网络频繁遭遇外部攻击&#xff0c;我们得加强一下网络安全了。” 小张&#xff1a;“是啊&#xff0c;我听说实施网络准入控制是个不错的选择。但具体什么是网络准入控制设备&#xff1f;我们有哪些选择呢&#xff1f;” 小李微笑…