转帖地址: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多线程编程环境中单例模式的实现
c++中单例模式对象的释放控制,txt文件格式的,哈哈哈
主要介绍了Java中单例模式详解,单例模式包括了懒汉式单例、饿汉式单例、登记式单例三种,想要了解的朋友可以了解一下。
主要介绍了java 中单例模式饿汉式与懒汉式的对比的相关资料,这里对这两种单例模式进行对比,希望大家能理解并应用,需要的朋友可以参考下
一个简单的java工程,包含注释,一目了然,其中包含了单例模式的所有实现方式,懒汉式,饿汉式,双重校验,枚举,静态内部类等方式实现单例。
主要介绍了Java中单例模式的7种写法,本文分别给出每种方式的实现代码,需要的朋友可以参考下
里面有单表的增删改查,多表级联的增删改查的操作,还囊括了我们常用的单选按钮,下拉列表,复选框的使用。对于初学者是个很不错的帮助工具,且分数也很低。
[常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到此类是否已经被实例化] 注:需要创建__clone()方法防治对象被复制作用: 1.php的应用主要用于数据库,所以一个应用中会存在大量的数据库...
# 单链表 Java 中单向链表的简单实现。
目前java中的单例模式有多种写法,kotlin中的写法更多一点,下面这篇文章主要给大家介绍了关于Kotlin中单例模式和Java对比的相关资料,会总结全部的到单例模式写法,需要的朋友可以参考下
主要介绍了深入解析Java的设计模式编程中单例模式的使用,一般来说将单例模式分为饿汉式单例和懒汉式单例,需要的朋友可以参考下
详细介绍了java中单例设计模式各种方式,已经改进方案
主要介绍了C#中单例的实现方法,以实例形式分析了C#中单例的原理与实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
本文主要介绍了PHP中单例模式与工厂模式的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
主要介绍了C#中单例模式的三种写法示例,本文分别给出代码实例,需要的朋友可以参考下
Java单例防止反射漏洞攻击是针对Java中单例模式的防护措施。由于Java的反射机制可以绕过类的私有构造方法创建对象,导致单例对象不再唯一,可能引发安全风险。为了防止这种漏洞,可以在单例类的私有构造方法中添加...
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。