整理自优快云论坛讨论版帖子:
原始提问:obj=null;是否能让对象立刻释放,是否能加快对象释放,是否有必要加上?
设置对象null只是段开了内存对象与引用句柄之间的引用关系,只是把引用转了个位,并没有让对象为null 。
对非托管对象:设置对象null只是段开了内存对象与引用句柄之间的引用关系。
垃圾回收器在释放对象的时候是无序的,即,不能确保对象释放时利用组合模式,从内向外或者从外向内释放。。。
//
个人认为加上obj=null是有助于内存回收的,观点如下:
1.垃圾回收器的运行时间是不确定的,微软有一套复杂的调度方案,不会在obj=null的时候被调用。
2.垃圾回收器的简单原理:当垃圾回收运行的时候,检查内存对象的引用,如果发现没有任何引用指向某内存,就回收 。
obj=null实际上是断开了引用和内存位置的连接,也就是使实际内存的引用计数减少了,只有当引用计数为0才会被垃圾回收器回收该内存。
3.垃圾回收器会对实际的已分配的内存,维护一个代龄。
垃圾回收器第一次运行,没有被回收的内存(此时肯定是因为还有别的对象引用到了它,才不会被回收)为一代。
垃圾回收器第二次运行,第一代中还没有被回收的,变成二代,本次非一代,但没有回收的,成为新的一代(实际上是两次运行间隔中心分配的)
第三次运行,就会产生三代,同样递归 而且垃圾回收器会优先回收第一代的可用内存 因此obj=null可以让被引用的内存块尽可能的被垃圾回收器认为是一代,因此会被优先回收。
最后,个人认为要测试obj=null是否可有助于内存回收,不应该是靠大数据量 而应该靠频繁的新建对象,丢弃对象,导致产生很多废引用,再看回收的时间,以此来评估垃圾回收器。
//
按我的理解,每个对象都是一个气球,当你要某一个气球的时候,就把它吹大,然后用一根绳子系着,同一个气球有可能被多个人同时牵着, 它还没破的时候就一直占用空间(内存),GC相当于一个专门扎破气球的人,不断观察附近哪个气球没有被牵着, 发现了以后就把它扎破,释放内存空间。
//
我们可以做一个这样的假设,就是一个对象创建之后,有两个变量指向它,然后把其中一个=null,那么这个时候是不会有释放的可能,那么这行代码是否会去告诉gc现在只有一个引用了呢?或者gc会依赖这条语句的结果来优化判断堆里的这块内存只有一个引用了呢?应该不会吧~~~
我想这么假设后应该比较明显了,=null只是让当前变量什么都不指向而已了,就像前面举的的气球的例子一样,这个动作只是隔断了牵引气球的一根绳子而已,它能告诉gc可以捅破气球了么?应该不会,因为可能还有另外一根绳子牵着呢。而且这个动作是否会去检查这个气球是否还有其他绳子牵着,如果没有的话就告诉gc捅破气球?如果是,那就违背了gc的设计目的了。由此说,gc是否去捅破气球,它不会因为有了=null的动作而进行优化,它仍然会去检查看这个气球有没有被绳子牵着,如果存在这个优化,那gc本身就会浪费许多资源,特别是在频繁创建对象,=null的情况下,但我觉得这是不可能的。
前面还有人说=null会让当前对象在gc里的代次发生变化,不知道是否有确切的依据呢,还是自己想象的。gc的目的就是让运行的代码不用去管内存,一个=null语句就去关心gc的代次,内存是否该回收了,那还要gc干嘛呢?