`

Java中单例对象不会被GC回收(转帖)

阅读更多

转帖地址:https://www.cnblogs.com/ljy-cloudy/p/7485078.html

hotspot虚拟机的垃圾收集算法使用根搜索算法。这个算法的基本思路是:对任何“活”的对象,一定能最终追溯到其存活在堆栈或静态存储区之中的引用。通过一系列名为根(GC Roots)的引用作为起点,从这些根开始搜索,经过一系列的路径,如果可以到达java堆中的对象,那么这个对象就是“活”的,是不可回收的。可以作为根的对象有:

  • 虚拟机栈(栈桢中的本地变量表)中的引用的对象。
  • 方法区中的类静态属性引用的对象。
  • 方法区中的常量引用的对象。
  • 本地方法栈中JNI的引用的对象。

     方法区是jvm的一块内存区域,用来存放类相关的信息。很明显,java中单例模式创建的对象被自己类中的静态属性所引用,符合第二条,因此,单例对象不会被jvm垃圾收集。

            虽然jvm堆中的单例对象不会被垃圾收集,但是单例类本身如果长时间不用会不会被收集呢?因为jvm对方法区也是有垃圾收集机制的。如果单例类被收集,那么堆中的对象就会失去到根的路径,必然会被垃圾收集掉。对此,笔者查阅了hotspot虚拟机对方法区的垃圾收集方法,jvm卸载类的判定条件如下:

    • 该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。
    • 加载该类的ClassLoader已经被回收。
    • 该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

            只有三个条件都满足,jvm才会在垃圾收集的时候卸载类。显然,单例的类不满足条件一,因此单例类也不会被卸载。也就是说,只要单例类中的静态引用指向jvm堆中的单例对象,那么单例类和单例对象都不会被垃圾收集,依据根搜索算法,对象是否会被垃圾收集与未被使用时间长短无关,仅仅在于这个对象是不是“活”的。

 

转帖地址:http://blog.csdn.net/u013216156/article/details/72624965

单例模式创建的对象是否会被JVM回收

在单例模式中,如果对象长久没有被使用,该对象是否会被JVM进行垃圾回收呢?
在回答这个问题之前得先弄懂JVM会在什么时候对对象进行垃圾回收的。

JVM如何判断一个对象需要被回收

   JVM判断一个对象是否需要被回收,得对这个对象进行可达性分析。所谓的可达性分析,     
就是判断这个对象是否有到达GC Roots的一个引用链,即是否能够到达这个GC Roots。   
即从GC Roots开始搜索,经过一系列的路径,如果可以到达java对象,那这个对象就是   
不可回收的。  
    既然,要判断对象是否可以被回收,得判断对象是否可达GC Roots,那GC Roots是什么?  
可以充当GC Roots的对象如下:
    - 虚拟机栈中的引用对象。  
    - 方法区中的类静态属性引用的对象。
    - 方法区中常量引用的对象。
    - 本地方法栈中JNI的引用对象。  
    通俗的讲,就是能否在方法区或者堆栈中找到一个该对象的引用,如果有这个对象就是不可  
回收的,如果没有JVM就会回收该对象。  

    知道了垃圾回收对象的方法之后,我们得弄懂单例模式中的对象的GC Roots是哪一种类型的。  

单例模式对象分析

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
        return instance;  
    }  
}   
    上面的单例模式是一个饿汉式的。由上面的代码可以知道,这个对象是被"private static" 
修饰的,因此,这个对象是从属于类的,它的GC Roots即为"方法区中的类静态属性引用的对象",  
所以,只要这个类加载到内存中且这个类还没有被垃圾回收,那这个对象就不会被垃圾回收。     
    既然,这个单例类被加载到内存中,这个单例对象就不会被垃圾回收。但是,如果这个类长时  
不使用,是否会被垃圾回收呢?那么,类是在什么条件下会被回收?

Java类垃圾回收的条件

    JVM对类的回收条件如下:
    1. Java堆中不存在该类的所有实例;
    2. 加载该类的ClassLoader已经被回收;
    3. 该类对应的java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类。
    JVM对类的回收要求比较严格,即使同时满足上面的所有条件也只是能够有资格回收类,但是  
并不能够保证一定会回收。  
    由上面的第一个条件可以知道,JVM要回收单例模式的类,该类需要满足堆中不存在该类的所有  
实例,但是单例模式中总是存在一个实例instance,所以该单例类也不会被垃圾回收。

总结

    通过上面的分析可以知道,单例模式的对象是不会被垃圾回收的,其中起关键作用的是我们得  
把该对象定义为"static"类型的。
分享到:
评论

相关推荐

    (源码)基于CS架构的轻量化分布式存储系统.zip

    # 基于CS架构的轻量化分布式存储系统 ## 项目简介 本项目是一个轻量化的分布式存储系统,采用CS架构设计,支持快速存取4MB到50GB的文件。系统分为客户端和服务端两部分,客户端负责文件的上传和下载,服务端负责文件的存储和管理。通过优秀的策略选择算法和分布式存储机制,系统能够高效地处理大文件和小文件的存储和传输。 ## 项目的主要特性和功能 分布式存储支持在多台服务器上分布式存储文件,提高存储容量和可靠性。 快速存取采用高效的策略选择算法,确保文件的快速存取。 文件切片支持将大文件切片存储,提高传输效率和可靠性。 多线程处理服务端采用多线程处理文件分块,提高并发处理能力。 自启动服务服务端支持自启动服务,方便管理和维护。 文件生成脚本提供文件生成脚本,方便测试和验证系统的传输速度和可靠性。 ## 安装使用步骤 ### 1. 环境准备 确保系统满足以下要求 CMake > 2.8.8

    小区开放对改善城市道路通行能力评估分析.pdf

    小区开放对改善城市道路通行能力评估分析.pdf

    中国区域创新能力评价报告【一级指标数据集】【更新至2024年】手动汇总

    中国区域创新能力评价报告【一级指标数据集】【更新至2024年】【手动汇总】

    便民医院挂号小程序的设计与实现+Java、小程序+医院挂号、小程序挂号

    随着信息化的发展,信息化和医疗的深度融合势在必行,当前很多国内外大型医院已经在信息化上面有很多投入,取得了一定成效。但是中小医院和乡镇卫生所等一线诊疗机构的信息化程度仍然有待提高,挂号成为了影响人们就诊的第一道坎,尤其是在疫情复发呈现点多线长面广的态势下,利用微信小程序的挂号系统对患者就诊和疫情防控都有重要意义。本文通过多方调研和访谈的方式,在分析了现有挂号系统的优劣之后,提出使用微信小程序实现挂号系统,可以有效降低用户使用负担,提升患者使用体验。经过分析,系统的主要功能有患者登录、患者注册、医生登录、医生管理、患者挂号、医生诊断的功能,经过系统规划和设计,使用用例图、实体关系图等多种方式完成了对系统的设计,经过测试,系统达到了建设目标。

    利用MOC设计最小长度二维平面钟形喷嘴Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    视频帧提取:将视频流切分为连续的帧 关键点提取:使用姿态估计模型(如 YOLOv8)提取每一帧中的人体关键点 时间序列数据构建:将每一帧的关键点位置(如肩膀、膝盖、头部等)作为特征,形成一个时间序

    视频帧提取:将视频流切分为连续的帧。 关键点提取:使用姿态估计模型(如 YOLOv8)提取每一帧中的人体关键点。 时间序列数据构建:将每一帧的关键点位置(如肩膀、膝盖、头部等)作为特征,形成一个时间序列。 LSTM 模型训练:使用 LSTM 模型来学习摔倒的时序模式。 摔倒判定:通过训练好的 LSTM 模型,实时分析时间序列,判断摔倒事件。

    Git 和 Github 的终极指南

    github Git 和 Github 的终极指南 文章亮点: Git 简介 Git 存储库结构 Github 的 通过 HTTPS 或 ssh 访问 Github 中央仓库 使用 git – 重要的 Git 命令

    MD5在线解密网站源码-集成多接口进行解密

    MD5在线解密网站源码_集成多接口进行解密

    集中式加密货币交易平台的设计与实现:系统架构、安全机制及优化策略

    集中式加密货币交易平台的设计与实现:系统架构、安全机制及优化策略

    lezhin_release_3588140.apk

    lezhin_release_3588140.apk

    手机卡号推广商城源码v1.31带后台/修复自助开通分站功能

    手机卡号推广商城源码v1.31带后台,修复自助开通分站功能。带有后台管理功能,可以添加产品和发布弹窗公告,非常适合开展号卡代理业务。该程序的源码十分精简,代码清晰易懂,即使没有编程经验的人也能够轻松上手使用。 该程序还配有一个弹窗公告功能,可以让你在网站上发布通知或广告信息,提高用户的活跃度和转化率。同时,该程序还支持在管理后台添加和编辑产品信息,方便管理者进行产品推广。总的来说,这是一款非常实用的号卡推广程序。 需要注意的是,该程序中有些外部文件未保存本地,建议在使用之前提前保存到本地以免失效。 安装教程 1.将数据库文件导入数据 默认账号admin 默认密码123456 在后台点击右上角个人中心修改密码。 2.修改untils目录下conn.php文件 修改里面的数据库名字、密码即可 3.后台地址为 域名/ssk 4.默认主站域名前缀:hao 如果要改主站域名前缀,到数据库info表格改domain字段,注意,不改的话,必须使用hao为域名前缀才能登录后台 5.开通分站域名在ktfz.php文件中修改一下网址即可 6.如果你网站开启了https,需要将css文件改

    用于十六进制到十进制转换的 Java 程序

    用于十六进制到十进制转换的 Java 程序

    db3e571e476144c4da6a0a3f1889b18a.part01

    db3e571e476144c4da6a0a3f1889b18a.part01

    php54-php-process-5.4.16-22.el6.centos.alt.x86_64.rpm

    php54-php-process-5.4.16-22.el6.centos.alt.x86_64.rpm

    华为市场管理流程指南(营销)-134页.pdf

    华为市场管理流程指南(营销)-134页.pdf

    php54-php-ldap-5.4.16-22.el6.centos.alt.x86_64.rpm

    php54-php-ldap-5.4.16-22.el6.centos.alt.x86_64.rpm

    (源码)基于Java和MySQL的订单管理系统.zip

    # 基于Java和MySQL的订单管理系统 ## 项目简介 本项目是一个基于Java和MySQL的简单订单管理系统,旨在帮助用户管理商品和订单信息。系统通过JDBC工具类与MySQL数据库进行交互,实现了商品和订单的增删改查功能,并提供了分页查询和排序功能。 ## 项目的主要特性和功能 1. 商品管理 商品的增删改查操作。 商品信息的排序和分页查询。 防止SQL注入攻击。 2. 订单管理 订单的增删改查操作。 订单信息的排序和分页查询。 订单与商品的关联查询。 3. 数据库操作 使用JDBC工具类进行数据库连接和操作。 事务管理,确保数据一致性。 异常处理和资源释放。 ## 安装使用步骤 1. 环境准备 确保已安装Java开发环境(JDK)。 安装并配置MySQL数据库。 下载并安装Datagrip图形化工具(可选)。

    年度年终绩效考核表.doc

    年度年终绩效考核表

    从入门到精通:图像识别项目实战指南

    从入门到精通:图像识别项目实战指南

    db3e571e476144c4da6a0a3f1889b18a.part23

    db3e571e476144c4da6a0a3f1889b18a.part23

Global site tag (gtag.js) - Google Analytics