一个所谓无用的类判断需要同时满足3个条件:
   1.该类的所有实例都已被回收,即Java堆中不存在该类的任何实例。
   2.加载该ClassLoader被回收。
   3.该类对应的Class对象没有在任何地方被引用,无法在任何地方反射该类的方法。   如果有一个类,包含一个静态成员变量,那么只要它被加载过一次,(事实上类在没有被销毁之前也只能加载一次)
是不是意味着这个类永远都不会被销毁,知道JVM结束?   疑问:一个类被加载后什么时候会被卸载呢?sun的原话是:"class or interface may be unloaded if and only if its class loader is unreachable. Classesloaded by the BootstrapClassLoader may not be unloaded."意思就是说类或接口可能不会被卸载除非ClassLoader是不能到达的,被BootstrapClassLoader加载的类可能不会被卸载。也就是说BootstrapClassLoader加载的部分基本不可能被卸载。      最后想说的是,如果我想在一些应用使用static做全局变量,这到底是不是安全的?会不会存在被回收的风险?大多数都是人都认为静态变量生命周期直到JVM结束。其实都是听别人说的,我想知道真实的原因,因为我对结果持怀疑态度。

解决方案 »

  1.   

    垃圾回收不是回收类,是回收对象。static属性属于类,不属于对象,所以对象被回收时,static并不能被回收。class所有对象都被回收之后可能会被卸载。
      

  2.   

    静态变量的生命周期取决于类的生命周期,当类被加载的时候,静态变量被创建并分配内存空间,当类被卸载时,静态变量被摧毁,并释放所占有的内存。另外,举个例子,如果两个对象相互引用的话,你就一直无法让对象引用为零了,所以 java 还引入了强引用和弱引用。jvm 的很多机制都很顾全大局,楼主可以去看《深入java虚拟机》去了解 java 底层的机制,知其所以然的过程是很兴奋的
      

  3.   

    简单说几句看对不对:
    1、毫无疑问的是,使用静态全局变量是没有风险的。如果有,那么问题就大了。
    2、静态变量回收的问题我想可以这么理解。首先它属于Class,也就是说,如果Class被回收,那么它就跟着被回收了。Class的回收机制比较复杂,但个人感觉如果简单理解的话,可以想像成类似于在jvm为每个Class保存一个引用计数。当计数变为0,则这个Class将有可能进入回收队列,否则,不可能被回收。进一步的讲,任何引用静态变量、类实例、类对象、静态方法等的代码都会导致Class的引用计数增加(但这种增加是以对象、类为单位的),如果引用计数为0,那么当然现有代码中就不存在使用与这个Class有关的任何资源的代码了,那么这个Class就可以被安排回收了。当然,如果之后动态加载了其它的类,又出现了对Class资源的引用,那么jvm还会加载它。大概是这个意思。
      

  4.   

    关于理解的问题,补充一点儿。
    可以想象jvm维持了一个类与对象的网络。每个类、每个对象都是一个节点,而引用就是节点之间的关系(有方向性,分依赖和被依赖)。当某个节点不被其它任何节点依赖(也许gc每次运行都会尝试遍历所有节点,并找到这种非依赖节点),那么就可以被安排回收了。当然,以上说法并不完全准确,仅仅是为了理解可以在头脑中这么想。实际情况并非如此,比如,节点的依赖关系中,就肯定有一种“自依赖”关系,比如一个正在运行的线程就是自依赖关系,没有任何东西依赖与它,但不能回收它。大概如此吧。
      

  5.   

    纠正下3楼,java采用的回收算法是根搜索算法,并非引用计数算法。2楼的意思:当类被卸载时,静态变量被摧毁 说明静态变量完全依赖类,类死必亡,同样说明了静态变量的不安全3楼的意思:矛盾,既认为静态变量是绝对安全的,又承认包含静态变量的类会被卸载掉,那就是非常不安全的我的意思:类一定在某个时候会被销毁(但是这个类必须不包含任何静态变量),反之包含静态变量的类在第一次加载后,必然不能被销毁,只有等到JVM结束,否则何谈静态变量是安全的说法。试想我这个静态变量是作为共享数据,并非是不可变final的,如果是final的,无所谓销毁就销毁吧。