将php 对象属性赋值为null,GC能回收吗

你正在使用的浏览器版本过低,将不能正常浏览和使用知乎。一直听说将不用的对象置为NULL,可以加迅被GC回收,但又听见另一种观点说置NULL不会被GC.倒底会不会加速呢,本人不太懂GC的机制,但也可以知道置NULL有没有用,写个代码测试一下就OK了.贴代码:public class LoopObject{public static void main(String[] args){LoopOfor (int i = 0; i & 100000; i++){lo = new LoopObject();}}}javac LoopObject.java为了公平,执行了五次运行命令,每执行一次,复制记录一下:java -verbosegc LoopObject结果如下:[GC 896K-&161K(5056K), 0.0013781 secs][GC 896K-&161K(5056K), 0.0013644 secs][GC 896K-&161K(5056K), 0.0013768 secs][GC 896K-&161K(5056K), 0.0013536 secs][GC 896K-&161K(5056K), 0.0013715 secs]被置为空后的代码:public class LoopObject{public static void main(String[] args){LoopOfor (int i = 0; i & 100000; i++){lo = new LoopObject();lo =}}}javac LoopObject.java为了公平,执行了五次运行命令,每执行一次,复制记录一下:java -verbosegc LoopObject结果如下:[GC 896K-&161K(5056K), 0.0013662 secs][GC 896K-&161K(5056K), 0.0013609 secs][GC 896K-&161K(5056K), 0.0013539 secs][GC 896K-&161K(5056K), 0.0013664 secs][GC 896K-&161K(5056K), 0.0014042 secs]结果对比,用前段代码的GC回收时间减去后一段代码的回收时间:0...0000229、-0.0000128、-0.0000327从结果上看,感觉差不多。。。。。。可能是例子太简单的,那么再写个复杂的代码import java.util.Hpublic class LoopObject{public static void main(String[] args){Hashtable&Object, Object&for (int i = 0; i & 100000; i++){ht = new Hashtable&Object, Object&();}}}javac LoopObject.java执行了三次运行命令,每执行一次,复制记录一下:java -verbosegc LoopObject结果如下:[GC 896K-&161K(5056K), 0.0013631 secs][GC 1057K-&161K(5056K), 0.0004871 secs][GC 1057K-&161K(5056K), 0.0002996 secs][GC 1057K-&161K(5056K), 0.0001650 secs][GC 1057K-&161K(5056K), 0.0001509 secs][GC 1057K-&161K(5056K), 0.0001557 secs][GC 1057K-&161K(5056K), 0.0001597 secs][GC 1057K-&161K(5056K), 0.0001625 secs][GC 1057K-&161K(5056K), 0.0002215 secs][GC 1057K-&161K(5056K), 0.0001568 secs][GC 896K-&161K(5056K), 0.0013520 secs][GC 1057K-&161K(5056K), 0.0005030 secs][GC 1057K-&161K(5056K), 0.0003084 secs][GC 1057K-&161K(5056K), 0.0001522 secs][GC 1057K-&161K(5056K), 0.0001523 secs][GC 1057K-&161K(5056K), 0.0001546 secs][GC 1057K-&161K(5056K), 0.0001626 secs][GC 1057K-&161K(5056K), 0.0001473 secs][GC 1057K-&161K(5056K), 0.0002252 secs][GC 1057K-&161K(5056K), 0.0001502 secs][GC 896K-&161K(5056K), 0.0013446 secs][GC 1057K-&161K(5056K), 0.0004839 secs][GC 1057K-&161K(5056K), 0.0003243 secs][GC 1057K-&161K(5056K), 0.0001527 secs][GC 1057K-&161K(5056K), 0.0001585 secs][GC 1057K-&161K(5056K), 0.0001537 secs][GC 1057K-&161K(5056K), 0.0001669 secs][GC 1057K-&161K(5056K), 0.0002167 secs][GC 1057K-&161K(5056K), 0.0001568 secs][GC 1057K-&161K(5056K), 0.0001760 secs]import java.util.Hpublic class LoopObject{public static void main(String[] args){Hashtable&Object, Object&for (int i = 0; i & 100000; i++){ht = new Hashtable&Object, Object&();ht =}}}重新编译后并执行javac LoopObject.java执行了三次运行命令,每执行一次,复制记录一下:java -verbosegc LoopObject[GC 896K-&161K(5056K), 0.0013605 secs][GC 1057K-&161K(5056K), 0.0004848 secs][GC 1057K-&161K(5056K), 0.0003503 secs][GC 1057K-&161K(5056K), 0.0001571 secs][GC 1057K-&161K(5056K), 0.0001541 secs][GC 1057K-&161K(5056K), 0.0001685 secs][GC 1057K-&161K(5056K), 0.0001570 secs][GC 1057K-&161K(5056K), 0.0001546 secs][GC 1057K-&161K(5056K), 0.0001561 secs][GC 1057K-&161K(5056K), 0.0001341 secs][GC 896K-&161K(5056K), 0.0014766 secs][GC 1057K-&161K(5056K), 0.0004738 secs][GC 1057K-&161K(5056K), 0.0003499 secs][GC 1057K-&161K(5056K), 0.0001562 secs][GC 1057K-&161K(5056K), 0.0001534 secs][GC 1057K-&161K(5056K), 0.0001450 secs][GC 1057K-&161K(5056K), 0.0001547 secs][GC 1057K-&161K(5056K), 0.0001607 secs][GC 1057K-&161K(5056K), 0.0001585 secs][GC 1057K-&161K(5056K), 0.0001300 secs][GC 896K-&161K(5056K), 0.0013647 secs][GC 1057K-&161K(5056K), 0.0004726 secs][GC 1057K-&161K(5056K), 0.0003491 secs][GC 1057K-&161K(5056K), 0.0001531 secs][GC 1057K-&161K(5056K), 0.0001437 secs][GC 1057K-&161K(5056K), 0.0001537 secs][GC 1057K-&161K(5056K), 0.0001530 secs][GC 1057K-&161K(5056K), 0.0001282 secs][GC 1057K-&161K(5056K), 0.0001714 secs][GC 1057K-&161K(5056K), 0.0001593 secs]从这次的结果中不难看出,多加了一行置空的代码,还真有点效果,只是不知道这些效果对系统性能有没有什么提高呢
最新教程周点击榜
微信扫一扫[JVM]请问a = null,对于垃圾回收,有效果吗 - ITeye问答
[JVM]请问a = null,对于垃圾回收,有效果吗
如A a = new A();
.........
最后用完了 a=&
采纳的答案
随便说个,随便听听……
各个JVM的实现方式不同,设null有没有影响也是不一定的。也就是说如果想确定一用完某个对象马上就释放其占用的内存空间,没有在各JVM上都通用的办法。
于是就可以看些有趣的例子了。许多JVM的实现都会在合适的时候把字节码即时编译为机器码,在这过程中有可能做方法内联、无用代码消除等诸多优化。看这个假象例子:
public class Foo {
public void bar() {
A a = new A();
a.doTask(this);
public class Quux {
public void baz() {
Foo foo = getFoo();
for (int i = 0; i & 100000; i++) {
foo.bar();
doSomeLongTask();
private void doSomeLongTask() {
}
Foo.bar()是一个小方法,而且在一个高强度的循环里被调用,则如果Quux.bar()被多调用几次,在某些JVM上就有机会看到实际运行的Quux.baz()代码变成了类似这样:
public void baz() {
Foo foo = getFoo();
if (Foo.class == foo.getClass()) { // guarded inline method cache
for (int i = 0; i & 100000; i++) {
A a = new A();
a.doTask(foo);
for (int i = 0; i & 100000; i++) {
foo.bar();
// fallback
doSomeLongTask();
}
甚至有可能进一步把A.doTask()也内联进来。
这样,a这个引用的作用域就跑到Quux.baz()里了。
如果原先在Foo.bar()里写上了a =会怎样呢?
1、这句有可能原本就被优化掉了(因为这是对变量的赋值,而赋值后没有代码再读取过这个值)。反正方法调用结束后局部变量自然消失,设不设null都一样 && 前提是没内联优化。
2、这句没有一开始就被优化掉,而是被内联来到了Quux.baz()里:
public void baz() {
Foo foo = getFoo();
if (Foo.class == foo.getClass()) { // guarded inline method cache
for (int i = 0; i & 100000; i++) {
A a = new A();
a.doTask(foo);
for (int i = 0; i & 100000; i++) {
foo.bar();
// fallback
doSomeLongTask();
}
看起来似乎很有用对吧?似乎在Quux.baz()的中间就把a设为了null,减少了一个对new A()得到的对象的引用?
如果JVM有能力把代码内联进来,也就不差在计算变量的存活范围和消除无用代码了。于是a =照样被当作无用代码消除掉,同时也可以得知a变量的存货范围只有for循环里的两行,所以Quux.baz()的其它局部变量可以在其它时间占用a所在的寄存器或栈空间。设不设null还是一样。如果在执行doSomeLongTask()时进行GC,即时不设置a为null,GC也会认为没有那个引用,不影响可能的回收。
但如果没那么多优化,JVM就老老实实的执行没优化过的字节码呢?
public void baz() {
Foo foo = getFoo();
A a = new A();
a.doTask(foo);
doSomeLongTask();
}
JVM可能会老老实实把全部局部变量都放在栈帧上,可能不消除无用代码,可能在doSomeLongTask()的执行过程中进行了GC。如果a没有被手工设为null,则GC的时候会看到栈上还存在一个指向new A()得到的对象的引用,于是认为该对象还是活的。
手工设置null最有用的场景恐怕就是在特定JVM上配合System.gc()来用了吧 =v=
和你使用的引用类型有关系的,看看这篇文章对你应该有帮助:
这样是一种好的编程习惯,对于垃圾回收有部分效果,不是绝对的,
啊,打错字……
假象=&假想
存货=&存活 OTL
有效果,a = null 后,就去掉了一个指向 new A() 出来的那个对象的引用。
没有被任何符号引用或间接的对象,就会进入收垃圾的列表里,gc 有空就会把它收拾掉。如果想早点见到效果,可以调用 System.gc()。注意 gc 不受你管,所以 System.gc() 只是建议,不是命令。
要注意的是:这样不一定去掉了所有引用。
譬如 a = new A() 后, b = a, a = null 不能使这个对象进入 gc 列表。
对重复创建千百万次的对象,可以这么做增加点保障,但是我觉得形成习惯就不好了。
一来不一定解决漏内存问题,二来影响可读性 …… 如果还要程序员自己管理内存,挨个设 null,和 C++ 还有什么区别 ?
这样是一种良好到编程习惯,
如果你有jprofile到话,你=null后,然后调用 System.gc() 看看效果,你就知道了
已解决问题
未解决问题}

我要回帖

更多关于 python 对象属性赋值 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信