锁定老帖子 主题:java代码调优笔记(一)
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-10-29
quxiaoyong 写道 cuishen 写道 (3). 用StringBuffer的append方法代替"+"进行字符串相加。 这个已经被N多人说过N次了,这个就不多说了。 貌似StringBuilder比StringBuffer效率更好点。如果在单线程内的话。记得是这样 如果真要考虑性能优化,这么几句话还是没有说到位。 之所以要用StringBuilder或者StringBuffer代替 "+",不在于append方法, 这个大家都知道的,现在编译器会自动把"+"编译成StringBuilder, 关键在于自己写的StringBuilder可以设定capacity |
|
返回顶楼 | |
发表时间:2011-10-29
caonimalaobi 写道 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个好算少的? 第一有这么多吗?第二会同时运行吗? 这些玩意基本在栈里, 应该不用你担心的吧 多不多看项目大小 同时当然会了,多线程到处都是,然道你的系统都是一个人用? 不管在栈还是在堆,积少成多。 |
|
返回顶楼 | |
发表时间:2011-10-29
luzhecheng 写道 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还是没问题的 嗯,同意,要注重可读性,事先将变量都声明的方式,我觉得是C那个年代的必须做法了。 |
|
返回顶楼 | |
发表时间:2011-10-29
同意楼上的说法,在现在的编译器下,我们还是要更注意代码的可读性。放在循环内申明,既增加可读性,有可以限定作用域。
|
|
返回顶楼 | |
发表时间:2011-10-29
建议楼主好好学学基础再来调优,特别是第六点,典型的人云亦云。
|
|
返回顶楼 | |
发表时间:2011-10-29
最后修改:2011-10-29
cuishen 写道 (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); } 采用上面的第二种编写方式,仅在内存中保存一份对该对象的引用,而不像上面的第一种编写方式中代码会在内存中产生大量的对象引用,浪费大量的内存空间,而且增大了垃圾回收的负荷。因此在循环体中声明创建对象的编写方式应该尽量避免。 坚决反对这类调优,new Object()产生的内存在堆里,第一种和第二种空间的占有是一样的,区别在于栈内引用指针个数。 第二种无疑将将变量作用域扩大,极有可能因为误操作导致Regression. 你不能保证后面修改程序的人和你一样细心,也不能保证别人和你一样”高“水平 |
|
返回顶楼 | |
发表时间:2011-10-30
都是些自以为是的“优化”
|
|
返回顶楼 | |
发表时间:2011-10-30
且某些jvm实现完全可以重用obj这个引用嘛
Ben.Sin 写道 cuishen 写道 (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); } 采用上面的第二种编写方式,仅在内存中保存一份对该对象的引用,而不像上面的第一种编写方式中代码会在内存中产生大量的对象引用,浪费大量的内存空间,而且增大了垃圾回收的负荷。因此在循环体中声明创建对象的编写方式应该尽量避免。 坚决反对这类调优,new Object()产生的内存在堆里,第一种和第二种空间的占有是一样的,区别在于栈内引用指针个数。 第二种无疑将将变量作用域扩大,极有可能因为误操作导致Regression. 你不能保证后面修改程序的人和你一样细心,也不能保证别人和你一样”高“水平 |
|
返回顶楼 | |
发表时间:2011-10-30
Object obj = null;
for (int i = 0; i < 10000; ++i) { obj = new Object(); System.out.println("obj= "+ obj); } 感觉两种方式没多大差别,如果变量除了for作用域不被引用都被回收,而且最后一个obj引用范围还扩大了,!!! |
|
返回顶楼 | |
发表时间:2011-10-30
赞成楼上说的.在编写代码时,尽量使作用域最小化.
|
|
返回顶楼 | |