JAVA性能等等杂谈

原文地址:http://www.javaeye.com/topic/9115

其中有些精彩的论述,以下为摘抄:

gigix 写道
EJB容器提供pool,仅仅是因为从前的JVM GC效率太低,不得不采用的权宜之计。在Java 1.3之后的VM里面,GC效率的提升已经使EJB容器的instance pooling变成了一个反模式。详情请参见J2EE without EJB第12章,或请教dlee同志。


确实是这样,如果不大清楚 GC 的分代机制,建议读一下相关的文档。我只简单说一下。所有现代的 JVM 都实现了分代的 GC。就是把内存的堆空间分成了两部分:“年轻一代”和“老一代”。刚刚 new 出来的对象都在“年轻一代”中。GC 过程分成两种类型,频率很高的小收集和频率很低的大收集。小收集只扫描“年轻一代”存储区,释放掉所有没有被引用的对象。而经过若干次小收集都没有被释放的对象则会被转移“老一代”存储区中。大收集执行频率很低,因为需要扫描所有的堆空间,所以消耗的时间也是比较长的。但是如果理解了 GC 的这种分代机制,把代码写好,对象仅仅在需要使用时才创建,不再需要后立即释放,那么这样的对象永远不会进入“老一代”中,而现代 JVM 由于采用了高效的算法,对“年轻一代”所做的小收集的效率是非常高的。关于分代的垃圾收集,可以看看 developerWorks 上 Brian Goetz 写的一系列文章:http://www-900.ibm.com/developerWorks/cn/java/j-jtp10283/
http://www-900.ibm.com/developerWorks/cn/java/j-jtp11253/

分代的 GC 是在 JVM 1.3 以后的版本才出现的。EJB 由于孕育在 JVM 1.1 的年代,那个时候 GC 的效率比较低,于是设计者认为 pooling 资源对象对于提高性能是非常关键的。这个看法在当时确实是正确的,但是现在已经是 JVM 1.5 的时代了,因此 EJB 一成不变的 pooling 方法按照现在的观点看来是完全过时了。实际上现在效率最高的方法就是在用的时候直接 new 一个对象,用完了就立即释放。资源对象的 pooling 现在不再是必须的了,甚至不适当的 pooling 还会对分代 GC 的性能造成损害。其实现在很多场合下只有数据库连接是必须要 pooling 的资源对象。pooling 对于一个容器来说,完全不是其最主要的功能之一。即使容器不提供,我也可以自己写一个,或者使用开源的产品(Jakarta Commons、PoolMan,etc.)。关于资源对象的 pooling,Rod Johnson 在 without EJB 第 12 章有很详细的讨论。

对于提高性能的追求要有一个度,不能太片面。如果性能的优化大幅度降低了代码的可读性(产生了非常复杂和难以理解的代码),那么我宁愿不去做这种性能优化。因为以后理解这些代码将花费了我们一个程序员大量的时间,从成本上来说是不划算的。
一段写的很差的代码,造成了性能的下降。我们需要做的第一件事不应该是直接加以修改以提高性能,而应该是先对这一段代码进行重构,消除掉其中大部分的臭味。经过良好重构的代码的性能是不会很低的,而且重构后得到了更好的代码结构,对于以后做性能优化提供了非常好的基础(可以更加方便地做性能优化)。我们可以找出一段写的非常差的代码,我来做重构,flyingbugs 来直接做性能优化,我们来看一下最后的结果性能究竟能差多少。
如何做好代码重构,建议去认真读一读侯捷和 gigix 共同翻译的《重构》。

flyingbugs 写道
1.在关键的地方 少使用Exception,特别是不要使用Exception来判断流称。
2.尽量减少不必要的new操作(注意,是不必要的,不要为了方便,而随便new一把)。
3.同步!!尽力避免同步的发生,除非在没有办法的办法情况下。 很多时候,同步是可以通过适当的数据结构和算法调整来实现的。
4.对于瓶颈发生的地方,仔细考虑软硬件环境,必要的时候,需要修改算法,用自己的特定的算法来改造。


1、2、4 我基本上同意。对于 3 我要纠正一下,很多时候影响性能的不是同步本身,而是是否存在对锁的竞争和是否有效避免了竞争,所以不要简单地对使用同步畏之如虎。同步如果能用好,很多时候对于性能的影响是不大的。这个观点 Rod Johnson 在 without EJB 第 12 章中同样有详细的讨论。

说点题外话,这个主题虽然很长,但是大多没有多少内容(感觉不过瘾),还陷入了不必要的口水战。其实就是一个以前在这里讨论的很充分的老问题:究竟是 OOP 重要还是算法重要?我的看法是,OOP 解决的主要还是软件结构方面的问题,算法解决的是软件细部的问题,两者都是非常重要的。一个好的程序员必须同时是 OOP 和算法的高手。但是在大多数开发工作中(例如一般的 MIS、ERP 应用,复杂性更多的发生在业务逻辑上而不是在算法本身上面),OOP 的成分更多一些。即使 OOP 用熟了(设计模式查都不用查直接写出来),算法、数据结构仍然是软件开发的基础。OOP 也可以看作是一种高级的数据结构,当然它除了数据本身的组织,还包括可以在数据之上执行的操作的组织。程序 = 数据结构 + 算法,这个等式大家都不会忘记吧?那么我们有什么必要单纯强调一方而忽视另一方呢? Java 把一些常用的数据结构和算法都封装起来了(直接封装在 Java 核心类库中),提供了一个 OO 的 API 让开发人员访问,所以开发人员自己去实现一些基本算法的场合就比较少了(当然 C++ 也有封装的非常好的 STL)。以至于 Martin Fowler 都感叹我们在 OO 方面走了这么远以后是不是把学校里面学习的那些数据结构、算法都忘掉了。但是现在必须由应用的开发人员(是做普通的应用,不是做底层类库的开发)自己去实现复杂算法的场合确实并不多。如果有这样的场合,那就只好再把这些东西捡回来了,而如果要用到更加复杂的算法,就只好去啃《计算机程序设计艺术》或者专业的论文了。当然如果有封装的很好的开源类库可以直接使用,那就最省事了。100% OO 仅仅是一个审美上的选择(我现在也更喜欢采用 OO 方式封装的很好的组件,因为使用起来确实更方便),而并不是什么清规戒律。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值