锁定老帖子 主题:讨论:单例和静态方法的深入讨论
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (3)
|
|
---|---|
作者 | 正文 |
发表时间:2011-01-10
aabcc 写道 按我的理解,ClassLoader中,如果调用了 defineClass后就不能在该 ClassLoader中remove了
前面几位高手都说能卸载,求教卸载类的方法... 按我的理解,被ClassLoader装载过的类应该是有被ClassLoader中不可操作的强引用所引用,只有在classLoader本身被GC时,被该CLASSLOADER装载过的CLASS才有可能被GC(还要排除ClassLoader以外没有任何强引用去引用该class) 如果我理解错了,求批。 是这样吗?没有任何引用的时候就会被GC掉,跟加载他的CLASSLOADER没关系吧。 |
|
返回顶楼 | |
发表时间: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(); |
|
返回顶楼 | |
发表时间: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 |
|
返回顶楼 | |
发表时间: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队列。 |
|
返回顶楼 | |
发表时间: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! |
|
返回顶楼 | |
发表时间:2011-01-10
看看 《深入java虚拟机》那里有你要的答案
|
|
返回顶楼 | |
发表时间: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() 则说明了以上结论 |
|
返回顶楼 | |
发表时间: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的引用的。 |
|
返回顶楼 | |
发表时间: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个对象呢? |
|
返回顶楼 | |
发表时间:2011-01-10
超级潜水员 写道 蛋疼的忧虑,从没有担心class占内存及回收的,你就算有几亿行代码吧? 能占1G内存么?
天哪,如果一个程序假如就能占1G内存的话,完蛋了,还让不让操作系统干活了? 占内存的多少根代码行数没有直接关系吧 while (true) { Object o = new Object(); } 三行代码能占多少内存? |
|
返回顶楼 | |