论坛首页 Java企业应用论坛

讨论:单例和静态方法的深入讨论

浏览 14183 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (3)
作者 正文
   发表时间:2011-01-10  
aabcc 写道
按我的理解,ClassLoader中,如果调用了 defineClass后就不能在该 ClassLoader中remove了

前面几位高手都说能卸载,求教卸载类的方法...

按我的理解,被ClassLoader装载过的类应该是有被ClassLoader中不可操作的强引用所引用,只有在classLoader本身被GC时,被该CLASSLOADER装载过的CLASS才有可能被GC(还要排除ClassLoader以外没有任何强引用去引用该class)

如果我理解错了,求批。


是这样吗?没有任何引用的时候就会被GC掉,跟加载他的CLASSLOADER没关系吧。
0 请登录后投票
   发表时间:2011-01-10   最后修改:2011-01-10
imacback 写道
aabcc 写道
按我的理解,ClassLoader中,如果调用了 defineClass后就不能在该 ClassLoader中remove了

前面几位高手都说能卸载,求教卸载类的方法...

按我的理解,被ClassLoader装载过的类应该是有被ClassLoader中不可操作的强引用所引用,只有在classLoader本身被GC时,被该CLASSLOADER装载过的CLASS才有可能被GC(还要排除ClassLoader以外没有任何强引用去引用该class)

如果我理解错了,求批。


是这样吗?没有任何引用的时候就会被GC掉,跟加载他的CLASSLOADER没关系吧。


// The classes loaded by this class loader.  The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private Vector classes = new Vector();


0 请登录后投票
   发表时间:2011-01-10  
aabcc 写道
imacback 写道
aabcc 写道
按我的理解,ClassLoader中,如果调用了 defineClass后就不能在该 ClassLoader中remove了

前面几位高手都说能卸载,求教卸载类的方法...

按我的理解,被ClassLoader装载过的类应该是有被ClassLoader中不可操作的强引用所引用,只有在classLoader本身被GC时,被该CLASSLOADER装载过的CLASS才有可能被GC(还要排除ClassLoader以外没有任何强引用去引用该class)

如果我理解错了,求批。


是这样吗?没有任何引用的时候就会被GC掉,跟加载他的CLASSLOADER没关系吧。


// The classes loaded by this class loader.  The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private Vector classes = new Vector();





   又出现分支了:到底是类先被卸载还是该类的转载类(classLoader)先被卸载呢?
   我一直这样认为的:只有类被GC了,则就没有对它的classLoader对象的引用了,于是classLoader就会被GC
  
0 请登录后投票
   发表时间:2011-01-10  
躁动的绵羊 写道
aabcc 写道
imacback 写道
aabcc 写道
按我的理解,ClassLoader中,如果调用了 defineClass后就不能在该 ClassLoader中remove了

前面几位高手都说能卸载,求教卸载类的方法...

按我的理解,被ClassLoader装载过的类应该是有被ClassLoader中不可操作的强引用所引用,只有在classLoader本身被GC时,被该CLASSLOADER装载过的CLASS才有可能被GC(还要排除ClassLoader以外没有任何强引用去引用该class)

如果我理解错了,求批。


是这样吗?没有任何引用的时候就会被GC掉,跟加载他的CLASSLOADER没关系吧。


// The classes loaded by this class loader.  The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private Vector classes = new Vector();





   又出现分支了:到底是类先被卸载还是该类的转载类(classLoader)先被卸载呢?
   我一直这样认为的:只有类被GC了,则就没有对它的classLoader对象的引用了,于是classLoader就会被GC
  


class 是被 classLoader 引用的, class 没引用 classLoader。

一个 实例是否被 GC 跟 实例里面的 成员 是否被 GC 没关系。

你这种理解我表示很费解。

退一百步说,假如你的 成员是 弱引用 或者 软引用,成员被 GC了,对你的实例 是否被GC 没有判定上的影响,你的实例 还是 照 GC算法来 判定是否 入GC队列。
0 请登录后投票
   发表时间:2011-01-10  
aabcc 写道
躁动的绵羊 写道
aabcc 写道
imacback 写道
aabcc 写道
按我的理解,ClassLoader中,如果调用了 defineClass后就不能在该 ClassLoader中remove了

前面几位高手都说能卸载,求教卸载类的方法...

按我的理解,被ClassLoader装载过的类应该是有被ClassLoader中不可操作的强引用所引用,只有在classLoader本身被GC时,被该CLASSLOADER装载过的CLASS才有可能被GC(还要排除ClassLoader以外没有任何强引用去引用该class)

如果我理解错了,求批。


是这样吗?没有任何引用的时候就会被GC掉,跟加载他的CLASSLOADER没关系吧。


// The classes loaded by this class loader.  The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private Vector classes = new Vector();





   又出现分支了:到底是类先被卸载还是该类的转载类(classLoader)先被卸载呢?
   我一直这样认为的:只有类被GC了,则就没有对它的classLoader对象的引用了,于是classLoader就会被GC
  


class 是被 classLoader 引用的, class 没引用 classLoader。

一个 实例是否被 GC 跟 实例里面的 成员 是否被 GC 没关系。

你这种理解我表示很费解。

退一百步说,假如你的 成员是 弱引用 或者 软引用,成员被 GC了,对你的实例 是否被GC 没有判定上的影响,你的实例 还是 照 GC算法来 判定是否 入GC队列。



当调用ClassLoader#defineClass方法时,会释放前面一个版本的Class!
0 请登录后投票
   发表时间:2011-01-10  
看看 《深入java虚拟机》那里有你要的答案
0 请登录后投票
   发表时间:2011-01-10  
mercyblitz 写道
aabcc 写道
躁动的绵羊 写道
aabcc 写道
imacback 写道
aabcc 写道
按我的理解,ClassLoader中,如果调用了 defineClass后就不能在该 ClassLoader中remove了

前面几位高手都说能卸载,求教卸载类的方法...

按我的理解,被ClassLoader装载过的类应该是有被ClassLoader中不可操作的强引用所引用,只有在classLoader本身被GC时,被该CLASSLOADER装载过的CLASS才有可能被GC(还要排除ClassLoader以外没有任何强引用去引用该class)

如果我理解错了,求批。


是这样吗?没有任何引用的时候就会被GC掉,跟加载他的CLASSLOADER没关系吧。


// The classes loaded by this class loader.  The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private Vector classes = new Vector();





   又出现分支了:到底是类先被卸载还是该类的转载类(classLoader)先被卸载呢?
   我一直这样认为的:只有类被GC了,则就没有对它的classLoader对象的引用了,于是classLoader就会被GC
  


class 是被 classLoader 引用的, class 没引用 classLoader。

一个 实例是否被 GC 跟 实例里面的 成员 是否被 GC 没关系。

你这种理解我表示很费解。

退一百步说,假如你的 成员是 弱引用 或者 软引用,成员被 GC了,对你的实例 是否被GC 没有判定上的影响,你的实例 还是 照 GC算法来 判定是否 入GC队列。



当调用ClassLoader#defineClass方法时,会释放前面一个版本的Class!



引用
class没引用classLoader


这个我不太同意,我看《深入JVM》上写的是每个Class都有一个对其classLoader的引用。
证明: Class的 class.getClassLoader() 则说明了以上结论

0 请登录后投票
   发表时间:2011-01-10   最后修改:2011-01-10
1. lz的辅助类多到引起堆溢出,那还叫辅助类吗。简直就是过程式编程了。。。

2. 所谓“单例模式”,是类上有一个static的获取实例的方法且没有公开的构造器,而不是里面所有的方法都是static的。

3.
引用
经过对堆内存的分析,发现有大量的装载类对象没有被回收,而我的项目中使用了大量的辅助类(里面方法为static的)

ClassLoader对象没有被回收,跟被这个装载类所装载的类是否使用单例实现没有关系,跟类里面是否使用了static方法也没有关系。lz真正的关注点应该项目里是否自己创建了ClassLoader实例,并且出现了泄漏。如果没有,就看看没有被回收的ClassLoader究竟是谁实现的(全类名),在哪里创建的,是否持有大尺寸的内部属性(可能是第三方包的ClassLoader实例泄漏)。正常情况下,随便启动个应用服务器(tomcat之类),就可能load进去上千个类,也没听过会出现ClassLoader实例溢出的情况。在是否使用单例的角度去讨论是解决不了lz的问题的。

4.
引用
证明: Class的 class.getClassLoader() 则说明了以上结论

请看java.lang.Class的代码
    public ClassLoader getClassLoader() {
        ClassLoader cl = getClassLoader0();
        if (cl == null)
            return null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ClassLoader ccl = ClassLoader.getCallerClassLoader();
            if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
            }
        }
        return cl;
    }

    native ClassLoader getClassLoader0();

这样的实现代码是不能证明Class中持有了ClassLoader的引用的。
0 请登录后投票
   发表时间:2011-01-10  
躁动的绵羊 写道
mercyblitz 写道
aabcc 写道
躁动的绵羊 写道
aabcc 写道
imacback 写道
aabcc 写道
按我的理解,ClassLoader中,如果调用了 defineClass后就不能在该 ClassLoader中remove了

前面几位高手都说能卸载,求教卸载类的方法...

按我的理解,被ClassLoader装载过的类应该是有被ClassLoader中不可操作的强引用所引用,只有在classLoader本身被GC时,被该CLASSLOADER装载过的CLASS才有可能被GC(还要排除ClassLoader以外没有任何强引用去引用该class)

如果我理解错了,求批。


是这样吗?没有任何引用的时候就会被GC掉,跟加载他的CLASSLOADER没关系吧。


// The classes loaded by this class loader.  The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private Vector classes = new Vector();





   又出现分支了:到底是类先被卸载还是该类的转载类(classLoader)先被卸载呢?
   我一直这样认为的:只有类被GC了,则就没有对它的classLoader对象的引用了,于是classLoader就会被GC
  


class 是被 classLoader 引用的, class 没引用 classLoader。

一个 实例是否被 GC 跟 实例里面的 成员 是否被 GC 没关系。

你这种理解我表示很费解。

退一百步说,假如你的 成员是 弱引用 或者 软引用,成员被 GC了,对你的实例 是否被GC 没有判定上的影响,你的实例 还是 照 GC算法来 判定是否 入GC队列。



当调用ClassLoader#defineClass方法时,会释放前面一个版本的Class!



引用
class没引用classLoader


这个我不太同意,我看《深入JVM》上写的是每个Class都有一个对其classLoader的引用。
证明: Class的 class.getClassLoader() 则说明了以上结论




字段引用只是一个标识,真正的对象Java代码级别是没有办法知道的。

按照你的理论的话,数组对象是不是要重复N个对象呢?
0 请登录后投票
   发表时间:2011-01-10  
超级潜水员 写道
蛋疼的忧虑,从没有担心class占内存及回收的,你就算有几亿行代码吧? 能占1G内存么?

天哪,如果一个程序假如就能占1G内存的话,完蛋了,还让不让操作系统干活了?
占内存的多少根代码行数没有直接关系吧
while (true) {
    Object o = new Object();
}
三行代码能占多少内存?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics