再谈引用(强引用,软引用,弱引用,虚引用)的概念,回收方法区

   
再谈引用
    无论是通过引用计数算法判断对象的引用数量,还是通过可达性分析算法判断对象的引用链是否可达,判定对象是否存活都与“引用”有关。在JDK1.2之前,Java中的引用定义如下:如果reference类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。这种定义很纯粹,但是太过狭隘,一个对象在这种定义下自由被引用或者没有被引用两种状态,对于如何描述一些食之无味,弃之可惜的对象就显得无能为力。
    在JDK1.2以后,为了描述这样一类对象:当内存空间足够时,则能保留在内存中;如果内存空间在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。为此,JDK1.2对引用的概念进行扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种,这4中引用强度逐渐减弱。

       
  • 强引用是指在程序代码中普遍存在的,类似“Object obj = new Object()”这类的引用,只要强引用还存在,那么垃圾收集器永远不会回收掉被引用的对象。
  •    
  • 软引用用来描述一些还有用但是非必须的对象。比如缓存。在系统将要发生内存溢出异常之前,垃圾收集器将会把这些对象列紧回收范围之中进行第二次回收。如果这次回收后还是没有足够的内存,那么会抛出内存溢出异常。在JDK1.2以后,提供了SoftReference类来实现软引用。
  •    
  • 弱引用也是用来描述非必须对象的,它的强度比软引用更弱一些,呗弱引用关联的对象只能生存到下一次垃圾回收发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK1.2以后,提供了WeakReference类来实现弱引用。
  •    
  • 虚引用也被称为幽灵引用或者幻影殷勇,它是最弱的一种引用关系。一个对象是否有虚拟用的存在,完全不会对其生存时间构成影响,也无法通过一个虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK1.2以后,提供了PhantomReference类来实现虚引用。
  •    

回收方法区
    方法区也称为永久代,这里的垃圾收集主要回收两部分内容:废弃常量和无用的类。回收废弃常量与回收Java堆中的对象非常类似。
    常量池中主要包含字面量、类(接口)、方法、字段的引用符号。
    判断常量是否可回收的条件未:没有其他地方引用了这个字面量。
    判断类是否可以(注意,这里仅仅是可以回收,不是必然回收)回收的条件有3个:
    1、该类的实例都已经被回收,即Java堆中不存在该类的任何实例。
    2、加载该类的ClassLoader已经被回收。
    3、该类对应的java.lang.Class对象没有在任何地方被引用,并且无法在任何地方通过反射访问该类的方法。
    是否对类进行回收,Hotspot虚拟机提供了-Xnoclassgc参数,-verbose:class以及-XX:+TraceClassLoading、-XX:+TraceClassUnloading查看类加载和卸载信息,其中-verbose:class和-XX:TraceClassLoading可以在Product版的虚拟机中使用,-XX:+TraceClassUnloading参数需要FastDebug版的虚拟机支持。
    在大量使用反射、动态代理、cglib等bytecode框架、动态生成jsp以及osgi这类频繁自定义ClassLoader的场景都需要虚拟机具备卸载的功能,以保证方法区(永久代)不会溢出。
   

猜你喜欢

转载自xiaoyun34286136.iteye.com/blog/2328226