`

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"类型的。
分享到:
评论

相关推荐

    浅谈Java中单例设计模式之构造方法私有化.pdf

    "浅谈Java中单例设计模式之构造方法私有化" 单例设计模式是 Java 中一种常用的设计模式,核心思想是将类的构造方法私有化,以控制实例化对象的产生。这种模式可以确保在程序中只有一个实例化对象存在,这对控制对象...

    JAVA中单例模式的几种实现方式.doc

    ### JAVA中单例模式的几种实现方式 #### 1. 线程非安全的基本实现方式 单例模式是设计模式中的一种常用形式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式可以通过多种方式来...

    Java多线程编程环境中单例模式的实现

    ### Java多线程编程环境中单例模式的实现 #### 概述 单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式的应用非常广泛,特别是在资源管理、日志记录、...

    java 中单例模式饿汉式与懒汉式的对比

    java 中单例模式饿汉式与懒汉式的对比 java 中单例模式是保证一个类仅有一个实例,并提供一个访问它的全局访问点的设计模式。单例模式有以下特点:单例类只能有一个实例,单例类必须自己自己创建自己的唯一实例,...

    java单例模式实例

    这种实现方式是在类被首次请求时才创建单例对象,延迟了初始化过程,从而提高了程序的启动性能。但这种方式有一个问题,即线程不安全。在多线程环境下,可能会创建多个实例。例如: ```java public class Singleton...

    c++中单例模式对象的释放控制

    在析构函数中检查并删除单例对象,确保其在程序结束前被正确释放。 ```cpp class CSingleton { public: static CSingleton* GetInstance() { if (m_pInstance == nullptr) m_pInstance = new CSingleton{}; ...

    Java中单表和多表级联的增删改查

    "Java中单表和多表级联的增删改查"这个主题涵盖了基础的数据库操作以及更复杂的关联查询技术。以下是对这些知识点的详细解释: 1. **单表的增删改查(CRUD)**: - **Create(创建)**: 在Java中,通常使用JDBC...

    Java中单例模式详解

    懒汉式单例的特点是在类第一次被使用时才创建实例,延迟加载,以节省资源。然而,非线程安全的懒汉式单例在多线程环境下可能导致多个实例的创建。上述代码中的`Singleton`类就是一个典型的懒汉式实现,但在多线程...

    Java中单例模式的7种写法

    Java中的单例模式是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。下面将详细介绍7种不同的Java单例模式实现方式: 1. **懒汉式(非线程安全)**: 这是最简单的实现,延迟初始化,但在多线程...

    Kotlin中单例模式和Java的对比浅析

    Kotlin 中单例模式和 Java 的对比浅析 Kotlin 中单例模式是指在应用程序中确保某个类仅有一个实例,并提供一个全局访问点的机制。单例模式是一种常用的设计模式,在 Java 和 Kotlin 中都有多种实现方式。下面我们将...

    java单点登录流程及其他

    Java 单点登录流程及其他 Java 单点登录(SSO)是指在多个系统或应用程序中,只需要用户登录一次,就可以访问所有相关系统或应用程序的机制。单点登录 OOS(Object-Oriented Security)通常包括身份验证...

    基于php设计模式中单例模式的应用分析

    4. **防止克隆**:由于对象克隆可能导致多个实例的存在,所以需要重写`__clone()`魔术方法,禁止对象被克隆。在PHP中,可以通过抛出错误或者返回错误信息来实现。 单例模式在PHP中的主要作用有: 1. **减少资源...

    C#中单例的实现方法

    本文实例讲述了C#中单例的实现方法。分享给大家供大家参考。具体实现方法如下: 代码如下: #region “实现这个窗口类的单例,单例类常用于被主窗口以show()方法打开的窗口,使用单例后只会打开一个此类的对象”  /...

    CIDRUtils.java 判断IP是否在指定范围内

    java判断IP是否在指定范围内,支持IPV4和IPV6。

    Python中单例模式总结

    `__new__`方法在创建新对象时被调用,可以在这里控制实例化过程。通过在类中重写`__new__`,确保只有一次实例化发生。 ```python class Singleton(object): _instance_lock = threading.Lock() def __new__(cls...

    SinglyLinkedList:Java中单向链表的简单实现

    单向链表是一种基本的数据结构,它在计算机科学中被广泛使用,特别是在处理动态数据集合时。在Java中,单向链表(Singly Linked List)由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的引用。这种...

    深入解析Java的设计模式编程中单例模式的使用

    在饿汉式单例中,`singleton`对象在类加载时即被创建,因此无论何时调用`getInstance()`方法,都能立即返回同一个实例。 **懒汉式单例**: 懒汉式单例在首次调用`getInstance()`方法时才进行实例化,因此类加载速度...

    Android中单例模式的一些坑小结

    本篇文章将详细探讨Android中单例模式的坑以及如何避免它们。 首先,让我们分析非线程安全的单例模式。以下是一个简单的非线程安全单例类: ```java class Singleton { private static Singleton singleton; ...

    Java实现多种单例模式

    代码中单例对象在类加载时即被创建。 ```java public class SingleInstance2 { private static final SingleInstance2 instance = new SingleInstance2(); private SingleInstance2() {} public static ...

Global site tag (gtag.js) - Google Analytics