一个所谓无用的类判断需要同时满足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.该类的所有实例都已被回收,即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、毫无疑问的是,使用静态全局变量是没有风险的。如果有,那么问题就大了。
2、静态变量回收的问题我想可以这么理解。首先它属于Class,也就是说,如果Class被回收,那么它就跟着被回收了。Class的回收机制比较复杂,但个人感觉如果简单理解的话,可以想像成类似于在jvm为每个Class保存一个引用计数。当计数变为0,则这个Class将有可能进入回收队列,否则,不可能被回收。进一步的讲,任何引用静态变量、类实例、类对象、静态方法等的代码都会导致Class的引用计数增加(但这种增加是以对象、类为单位的),如果引用计数为0,那么当然现有代码中就不存在使用与这个Class有关的任何资源的代码了,那么这个Class就可以被安排回收了。当然,如果之后动态加载了其它的类,又出现了对Class资源的引用,那么jvm还会加载它。大概是这个意思。
可以想象jvm维持了一个类与对象的网络。每个类、每个对象都是一个节点,而引用就是节点之间的关系(有方向性,分依赖和被依赖)。当某个节点不被其它任何节点依赖(也许gc每次运行都会尝试遍历所有节点,并找到这种非依赖节点),那么就可以被安排回收了。当然,以上说法并不完全准确,仅仅是为了理解可以在头脑中这么想。实际情况并非如此,比如,节点的依赖关系中,就肯定有一种“自依赖”关系,比如一个正在运行的线程就是自依赖关系,没有任何东西依赖与它,但不能回收它。大概如此吧。