日期:2014-05-20  浏览次数:20843 次

循环外声明对象和循环内声明对象的问题
1.循环内声明对象
Java code

for(int i = 0;i < len ; i ++){
  Object o = new Object();
}


2.循环外声明对象
Java code

Object o = null;
for(int i = 0;i < len ; i ++){
  o = new Object();
}



大家都用哪种方式的?
哪个的运行效率高,
从垃圾回收方面看,哪个比较好

------解决方案--------------------
两个差不多,看你的问题了,有时候还必须用第二种呢!
------解决方案--------------------
jvm可以做出很多优化的,这个事情说不好
------解决方案--------------------
咱以为是第二种~
------解决方案--------------------
其实没什么差别的,给如下一个例子你可能就知道了

public void dot1(){
for(int i=0;i<100;i++){
dot2();
}
}

public void dot2(){
int i = 0;
Object obj = new Object();
//more....
}

在dot1的循环中,不断要调用方法dot2,这个应该是很容易理解的常见现象吧。然后在dot2中又会定义多个变量并新建实例。如果dot2只为dot1服务,那这和在dot1的for循环中直接new 变量没什么差别。


还有,sun的程序员也是这么用的。在for 或者 while中new 对象。可以去jdk source中去找一下。
------解决方案--------------------
探讨
1.循环内声明对象
Java code

for(int i = 0;i < len ; i ++){
Object o = new Object();
}


2.循环外声明对象
Java code

Object o = null;
for(int i = 0;i < len ; i ++){
o = new Object();
}



大家都用哪种方式的?
哪个的运……

------解决方案--------------------
探讨
对于性能要求比较高的场景,不如手机游戏开发,对内存要求特别高。这时,就必须采用第二中方案。
理由:
1.第一种方案假如循环了1W次,则在短时间将生成1W个临时变量,同时系统别的地方都这样写,则会占用大量的内存,很可能导致程序挂掉。而第二种始终只有1个临时变量。

------解决方案--------------------
个人认为,第二种比较好!
------解决方案--------------------
你需要多少个对象?
如果只用一个,那就第二个方法;
如果多个,就第一种,但是这些对象出了循环生命周期就结束了。

------解决方案--------------------

我刚才又发现了另一个相关的问题,

如果采用这种方式
for(int i ;;) { Object obj = new Object(i++);}//注意一个死循环

obj占用栈内存,new 出来的这个Object占用堆内存。


当死循环运行到一个较长时间后,如果在整个for期间,有无穷多个obj存在的话,那它将在栈中占用无穷多地址;同时每个obj将指向堆中对应的一个new出来的Object();那么这样有一个问题,在此for期间,在堆中new 的Object() 总有一个obj引用他,直到for结束。

而本例中for不可能结束,也就是堆中永远new Object();栈中永远为obj分配地址。直到一个时间,应该以生堆或栈溢出的情况。

然而,本人在运行以上实例时,并没有发现有堆或栈溢出的情况,操作系统为此虚拟机分配的内存总是在涨了4个字节后,又收回4个字节。 于是,本人判断,收回4个字节是不是垃圾回收机制收回了堆中new出来的Object(),因为栈不存在回收的问题,所以说堆中new出来的Object()在一定时间后,总有一总分不存在引用才被GC,此现像是否说明栈中的obj不存在无穷多外占用资源的问题(生成obj临时变量)。


以上现象,欢迎高手指正!

------解决方案--------------------
更正一下上实例中的语法:
for(int i=0 ;;) { Object obj = new Object(i++);}//注意一个死循环
------解决方案--------------------
喜欢瞎猜的人还是占大多说。
javap 处理一下,看栈空间占多少。