单例模式讨论篇:单例模式与垃圾回收

出处:http://blog.csdn.net/zhengzhb/article/details/7331354 

 

  Jvm的垃圾回收机制到底会不会回收掉长时间不用的单例模式对象,这的确是一个比较有争议性的问题。将这一部分内容单独成篇的目的也是为了与广大博友广泛的讨论一下这个问题。为了能让更多的人看到这篇文章,请各位博友看完文章之后,点一下“顶”,让本篇文章排名尽量的靠前。笔者在此谢过。

讨论命题:当一个单例的对象长久不用时,会不会被jvm的垃圾收集机制回收。

        首先说一下为什么会产生这一疑问,笔者本人再此之前从来没有考虑过垃圾回收对单例模式的影响,直到去年读了一本书,《设计模式之禅》秦小波著。在书中提到在j2ee应用中,jvm垃圾回收机制会把长久不用的单例类对象当作垃圾,并在cpu空闲的时候对其进行回收。之前读过的几本设计模式的书,包括《java与模式》,书中都没有提到jvm垃圾回收机制对单例的影响。并且在工作过程中,也没有过单例对象被回收的经历,加上工作中很多前辈曾经告诫过笔者:尽量不要声明太多的静态属性,因为这些静态属性被加载后不会被释放。因此对jvm垃圾收集会回收单例对象这一说法持怀疑态度。渐渐地,发现在同事中和网上的技术人员中,对这一问题也基本上是鲜明的对立两派。那么到底jvm会不会回收长久不用的单例对象呢。

        对这一问题,笔者本人的观点是:不会回收。

下面给出本人的测试代码

[java] view plaincopy
  1. class Singleton {  
  2.     private byte[] a = new byte[6*1024*1024];  
  3.     private static Singleton singleton = new Singleton();  
  4.     private Singleton(){}  
  5.       
  6.     public static Singleton getInstance(){  
  7.         return singleton;  
  8.     }  
  9. }  
  10.   
  11. class Obj {  
  12.     private byte[] a = new byte[3*1024*1024];  
  13. }  
  14.   
  15. public class Client{  
  16.     public static void main(String[] args) throws Exception{  
  17.         Singleton.getInstance();  
  18.         while(true){  
  19.             new Obj();  
  20.         }  
  21.     }  
  22. }  

        本段程序的目的是模拟j2ee容器,首先实例化单例类,这个单例类占6M内存,然后程序进入死循环,不断的创建对象,逼迫jvm进行垃圾回收,然后观察垃圾收集信息,如果进行垃圾收集后,内存仍然大于6M,则说明垃圾回收不会回收单例对象。

        运行本程序使用的虚拟机是hotspot虚拟机,也就是我们使用的最多的java官方提供的虚拟机,俗称jdk,版本是jdk1.6.0_12

        运行时vm arguments参数为:-verbose:gc -Xms20M -Xmx20M,意思是每次jvm进行垃圾回收时显示内存信息,jvm的内存设为固定20M。

运行结果:

……

[Full GC 18566K->6278K(20352K), 0.0101066 secs]

[GC 18567K->18566K(20352K), 0.0001978 secs]

[Full GC 18566K->6278K(20352K), 0.0088229 secs]

……

        从运行结果中可以看到总有6M空间没有被收集。因此,笔者认为,至少在hotspot虚拟机中,垃圾回收是不会回收单例对象的。

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

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

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

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

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

        只有三个条件都满足,jvm才会在垃圾收集的时候卸载类。显然,单例的类不满足条件一,因此单例类也不会被卸载。也就是说,只要单例类中的静态引用指向jvm堆中的单例对象,那么单例类和单例对象都不会被垃圾收集,依据根搜索算法,对象是否会被垃圾收集与未被使用时间长短无关,仅仅在于这个对象是不是“活”的。假如一个对象长久未使用而被回收,那么收集算法应该是最近最长未使用算法,最近最长未使用算法一般用在操作系统的内外存交换中,如果用在虚拟机垃圾回收中,岂不是太不安全了?以上是笔者的观点。

        因此笔者的观点是:在hotspot虚拟机1.6版本中,除非人为地断开单例中静态引用到单例对象的联接,否则jvm垃圾收集器是不会回收单例对象的。

        期待各位博友的发言。

 

参考文献

Java虚拟机规范

Java hotspot虚拟机内存管理

Java编程思想

Java与模式

设计模式

设计模式之禅

深入理解java虚拟机

转载于:https://www.cnblogs.com/Uinkanade/articles/4013762.html

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

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

相关文章

inline关键字

本文介绍了GCC和C99标准中inline使用上的不同之处。inline属性在使用的时候,要注意以下两点:inline关键字在GCC参考文档中仅有对其使用在函数定义(Definition)上的描述,而没有提到其是否能用于函数声明(Dec…

springmvc 组合注解

组合注解的意思就是一个注解中包含多个注解。在springmvc 的RestController中,你就可发现. Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented Controller ResponseBody public interface RestController {/*** The value may indicate a su…

人才管理是什么意思_上海托管仓库外包仓库管理什么意思

上海托管仓库外包仓库管理什么意思上海仓库托管外包。好的上海仓库托管是预估好自己的货物总计有多少个方。车子的体积有多少,然后估算出总计需要多少车需要多少钱,需要怎么装车、卸货码放方式是什么样的,算出总的费用然后包干给搬家公司。这…

window server 安装与卸载

安装window server 程序:C:\Windows\Microsoft.NET\Framework\v2.0.50727\installutil DataUpdateService.exe net start LuceneServer 卸载window server 程序:net stop LuceneServer C:\Windows\Microsoft.NET\Framework\v2.0.50727\installutil /U DataUpdateService.exe …

Makefile学习(二)[第二版]

复杂实例#示例1:在上一个示例的基础上再增加一个可执行文件03test[修改之处已标红].PHONY: clean all CC gcc CFLAGS -Wall -gBIN 01test 02test 03testSOURCES $(BIN:.c)OBJECTS $(BIN:.o)all: $(BIN)01test: 01test.o02test: 02test.o03test: 03test.o.c.o:$(CC) $(CFLA…

计算机网络asp视频教程,轻轻松松学编程!ASP互动视频教程

从2006年5月18日开始,PConline将与FIF联合推出国内网上第一部互动视频教程:《ASP互动视频教程》。它预示着一个全新的自助学习时代的到来。尽管相较于传统的图文教程,以前的多媒体视频课件优点非常明显,但它仍然存在交互性差的缺点…

Oracle查询和解锁表

一些ORACLE中的进程被杀掉后,状态被置为"killed",但是锁定的资源很长时间不释放,有时实在没办法,只好重启数据库。现在提供一种方法解决这种问题,那就是在ORACLE中杀不掉的,在OS一级再杀。1.下面…

三维家可以导入别人的方案吗_广州深圳天津形位公差检测三维缺陷检测服务

形位公差检测三维缺陷检测服务标签:形位公差检测 三维缺陷检测服务 三维缺陷检测铸造工艺是一种经济实惠的毛坯成形方式,对于一些形状复杂的零件更能显示出它的经济性。比如汽车发动机的缸体和缸盖,船舶螺旋桨以及精致的艺术品等。本期案例的…

计算机缺失esul.dll,SceneUI.ES.dll

我该如何安装从金山毒霸下载的DLL文件?一:1、从金山毒霸下载压缩文件。2、将DLL文件解压到电脑上的某个地方。3、把该文件跟要求使用它的程序放在同一路径上。注意32位程序需要使用32位的DLL文件,64位程序需要使用64位的DLL文件。否则会出现0…

android+ import R错误

import android.R; 在开发过程中有时候eclipse自动导入的包,该包有时候会导致一些奇怪的错误,再次出现该问题的时候,把import android.R;删掉。setContentView(R.layout.secondactivity); //不删掉 import android R;就会报错转载…

一、后台首页index.php【dedecms后台源码分析】

后台目录dede目录的所有问价的源码分析 使用的dedecms的版本5.7&#xff08;2012-04-01更新&#xff09; 后台登陆之后的首页分析dede/index.php <?php /*** 管理后台首页** version $Id: index.php 1 11:06 2010年7月13日Z tianya $* package DedeCMS.Admin…

transferto 文件不存在_文件上传时,MultipartFile.transferTo() 方法报 FileNotFoundException...

Spring Upload File 报错FileNotFoundException环境&#xff1a;Springboot2.0.4JDK1.8内嵌 Apache Tomcat/8.5.321、前端代码前端上传网页表单&#xff0c;enctype 和 input 的typefile 即可&#xff0c;使用单文件上传举例&#xff1a;图片2、后端代码RestControllerRequestM…

对“粘连”footer布局的思考和总结

经典的"粘连"footer布局 参考文章链接在文章末尾&#xff0c;简单的语言总结如下&#xff1a; 经典的“粘连”footer布局就是。我们有一块内容<main>。当<main>的高度足够长的时候&#xff0c;紧跟在<main>后面的元素<footer>会跟在<main…

计算机函数公式一等奖怎么算,信息技术应用 用计算机画函数图象教案设计(一等奖)...

卫鹏展地区&#xff1a; 湖北省 - 黄冈市 - 英山县学校&#xff1a;英山县金铺镇金铺中学 共1课时信息技术应用 用计算机画函数图象">信息技术应用 用计算机画… 初中数学 人教2011课标版 1教学目标1&#xff0e;结合具体情境理解一次函数的意义&#xff0c;能结…

这样去写你的 HTML

昨天在 twitter 上说&#xff0c;怎么忍心把页面写得这么难用&#xff1f;是的&#xff0c;这个世界还有一群人等着我们创建出来的东西&#xff0c;可以让他们的生活能过得更容易呢。比如那些需要读屏软件的用户。作为一个前端&#xff0c;我们又怎么会忍心呢。之前就一直想写这…

iframe懒加载_前端常见问题

原地址&#xff1a;https://blog.csdn.net/Mr_JavaScript/article/details/843110681. flex布局&#xff1a;又叫做弹性布局任何一个容器都可以指定flex布局&#xff0c;如display:flex 或 display:inline-flex注意&#xff1a;设置了flex布局以后&#xff0c;子元素的float&am…

手机运行服务器无响应,《最强蜗牛》服务器无响应怎么办 服务器无响应解决方法...

导读最强蜗牛服务器无响应怎么办&#xff1f;本作在今日迎来了正式的公测&#xff0c;这会导致大批量的玩家同时涌入进来&#xff0c;而服务器也因此而遭受到了非常大的符合&#xff0c;所以会导致后续加入进来的玩家出现服务器无响应进不去的现象。下面就为大家带...最强蜗牛服…

Android 开源框架Universal-Image-Loader学习

Android 开源框架Universal-Image-Loader完全解析&#xff08;一&#xff09;--- 基本介绍及使用 Android 开源框架Universal-Image-Loader完全解析&#xff08;二&#xff09;--- 图片缓存策略详解 Android 开源框架Universal-Image-Loader完全解析&#xff08;三&#xff09;…

自己动手写操作系统--个人实践

近期開始看于渊的《自己动手写操作系统》这本书&#xff0c;刚開始看就发现做系统的引导盘居然是软盘&#xff01;心里那个汗啊&#xff01; 如今都是U盘了&#xff0c;谁还用软盘。于是考虑用U盘。 于是開始下面步骤&#xff1a; 1、既然书上说给先要把软盘做引导盘&#xff0…

蔻驰和mk哪个更大牌_mk和coach哪个好?mk和coach包包是一个档次吗?

说到包包&#xff0c;mk和coach可谓是轻奢界的两大巨头了。因此&#xff0c;两个品牌的包包不可避免的会被经常拿来作比较。那么&#xff0c;从各个角度来讲mk和coach那款包包更好呢&#xff1f;这两款包包又有哪些本质上的区别呢&#xff1f;mk和coach哪个好价格对比大致上&am…