论坛首页 入门技术论坛

java代码调优笔记(一)

浏览 17006 次
该帖已经被评为新手帖
作者 正文
   发表时间:2011-10-29  
(3). 用StringBuffer的append方法代替"+"进行字符串相加。 

这个已经被N多人说过N次了,这个就不多说了。 



这个已经不成立了,,
除非在for循环中使用。







0 请登录后投票
   发表时间:2011-10-29  
个人觉得在java调优方面没有绝对的。我一个很小的项目随便怎么写,问题也不大的。在很大的项目中,不是通过这点点东西又能解决的。个人只是觉得在合适的场合用合适的语法或合适的逻辑,就OK!
0 请登录后投票
   发表时间:2011-10-29  
LookAtPic 写道
个人觉得在java调优方面没有绝对的。我一个很小的项目随便怎么写,问题也不大的。在很大的项目中,不是通过这点点东西又能解决的。个人只是觉得在合适的场合用合适的语法或合适的逻辑,就OK!

呵呵,节约是美德
0 请登录后投票
   发表时间:2011-10-29  
volking 写道
chenjingbo 写道
yjydmlh 写道
(6). 避免在循环体中声明创建对象,即使该对象占用内存空间不大。

这种情况在我们的实际应用中经常遇到,而且我们很容易犯类似的错误,例如下面的代码:
for (int i = 0; i < 10000; ++i) {
    Object obj = new Object();
    System.out.println("obj= " + obj);
}

上面的做法会浪费较大的内存空间。正确的做法如下所示:
Object obj = null;
for (int i = 0; i < 10000; ++i) {
    obj = new Object();
    System.out.println("obj= "+ obj);
}

采用上面的第二种编写方式,仅在内存中保存一份对该对象的引用,而不像上面的第一种编写方式中代码会在内存中产生大量的对象引用,浪费大量的内存空间,而且增大了垃圾回收的负荷。因此在循环体中声明创建对象的编写方式应该尽量避免。

我一直都是采用的第二种编写方式,没有原因,只是非常讨厌第一种编写方式,我也是后来才知道第一种方式不好的!

呵呵,无论是上面那种还是下面这种,堆内分配的对象都没有减少.至于说增加gc负担就更无从谈起了.
但是第二种方法会增加栈当中的引用数量.比如这个例子来说就是增加 9999个引用 ,差不多是40000byte ,也就是40K的开销..



你也不想想一个项目里会有多少个这样的循环?2000个好算少的?

如果逻辑要求有多种对象在循环内创建 我觉得第二种方式不利于代码的可读性 也不利于保护变量的作用域 而且一个项目中的循环虽然多 但只要不在同一方法体内被调用 gc还是没问题的
0 请登录后投票
   发表时间:2011-10-29  
chenjingbo 写道

呵呵,无论是上面那种还是下面这种,堆内分配的对象都没有减少.至于说增加gc负担就更无从谈起了.
但是第二种方法会增加栈当中的引用数量.比如这个例子来说就是增加 9999个引用 ,差不多是40000byte ,也就是40K的开销..

不会增加引用。
	public void test1(){
	    for (int i = 0; i < 10000; ++i) {  
	        Object obj = new Object();  
	        System.out.println("obj= " + obj);  
	    }  
	}
	
	public void test2(){
	    Object obj = null;  
	    for (int i = 0; i < 10000; ++i) {  
	        obj = new Object();  
	        System.out.println("obj= "+ obj);  
	    }  
	}

可以javap -verbose 看下class文件,两个函数占用的栈空间是一样大的。
Stack=3, Locals=3, Args_size=1

其实按照局部变量作用于最小化的原则,选择上一种写法更好。
9 请登录后投票
   发表时间:2011-10-29  
第6条,如果for里面的obj要作为参数复用,你new在for之外,你就挂了!!
0 请登录后投票
   发表时间:2011-10-29  
第六条绝对不能苟同;
放外面,for中最后new的对象作用域大了不少噻;
放里面,不会增加引用,楼上的楼上已经说明~!
0 请登录后投票
   发表时间:2011-10-29  
jvmlover 写道
chenjingbo 写道

呵呵,无论是上面那种还是下面这种,堆内分配的对象都没有减少.至于说增加gc负担就更无从谈起了.
但是第二种方法会增加栈当中的引用数量.比如这个例子来说就是增加 9999个引用 ,差不多是40000byte ,也就是40K的开销..

不会增加引用。
	public void test1(){
	    for (int i = 0; i < 10000; ++i) {  
	        Object obj = new Object();  
	        System.out.println("obj= " + obj);  
	    }  
	}
	
	public void test2(){
	    Object obj = null;  
	    for (int i = 0; i < 10000; ++i) {  
	        obj = new Object();  
	        System.out.println("obj= "+ obj);  
	    }  
	}

可以javap -verbose 看下class文件,两个函数占用的栈空间是一样大的。
Stack=3, Locals=3, Args_size=1

其实按照局部变量作用于最小化的原则,选择上一种写法更好。


stack=3代表栈的大小,还是深度,每一个栈帧中有局部变量表,里面保存的是变量引用吧

0 请登录后投票
   发表时间:2011-10-29  
hantsy 写道
wad12302 写道
Object obj = null;
for (int i = 0; i < 10000; ++i) {
    obj = new Object();
    System.out.println("obj= "+ obj);
}

只有一个引用obj ,循环一次换一个指向

但是 还是多创建了 9999个对象 ,如果没有引用回报回收


如果

System.out.println("obj= "+ obj);

的操作换成是

list.add(obj);//添加进List

想像这样的后果。

这样会有什么样的后果?不谈引用而言,与Object obj = new Object();这种写法有区别吗?
0 请登录后投票
   发表时间:2011-10-29  
cuishen 写道

(3). 用StringBuffer的append方法代替"+"进行字符串相加。

这个已经被N多人说过N次了,这个就不多说了。




貌似StringBuilder比StringBuffer效率更好点。如果在单线程内的话。记得是这样
0 请登录后投票
论坛首页 入门技术版

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