性能优化总结:
一个任务对数据库频繁操作,并且大量发送消息。时间暴长!
0. socket异常,rmi调用中传递大量数据出错、系统处理数据越来越慢。测试后发现缺省最大内存仅仅64M, -Xmx加大内存。
1. hibernate
    问题1: 数据第一次修改后保存成功,第二次修改不保存.
        跟踪hibernate后发现,flush认为数据在第二次修改后没有变化。俺们保存的对象中有个map属性,被定义为user type,映射到string. 因为是POJO,所以hibernate在判断对象有没有变化的时候取了所有属性列表,这个map是引用,比较前后都是它,看不出变化。如果用个新map就OK了,但是这样重新构造map消耗比较大,干脆直接把序列化以后的string作为属性,原来的map作为@Transient.
    问题2: 改过之后性能还是不高,从log看,读取到的对象没做任何修改也会被flush到数据库。再跟踪发现对象没做任何修改也会变化map string也会变化,仔细跟踪发现原来hash map无序,所以转换后string不一样,低级错误。用性能测试工具发现这个新的map转string属性被频繁调用,这个转换本来就比较耗时。解决办法,把转换做成lazy的,map有变化后才转换,转换后缓存之。
    问题3: 频繁读取数据库。同样查询有的作了很多次,应该缓存。query.setCacheable(true);加上后没效果,再跟踪发现hibernate.cache.use_query_cache没有设定为true :(
    问题4: 数据库事务加上、MO设定读缓存。
2. jms
    发现JMS消息频繁产生线程来发送消息,对任务加上JMS事务后,在任务结束后一次发送。
    activemq自己提供了连接池,用上
3. 低效的代码:
    很多方法很简单,但是在几万甚至上百万次调用后,很耗时。不必要的不要split, 有些可以简单去subString解决,需要的可以考虑apache的StringUtils.split(string,char),频繁split的可以缓存结果。
    有些对象注定不会重复,equals()方法直接比较引用。
    复杂不常用对象可以lazy init
4. 大量消息导致界面没有响应
    在接收到大量消息后,swing线程被大量SwingUtilities.invokeLater堵塞队列,用户事件不响应。考虑采用InvokeAndWait(), 发现效率不高。后来在每接收到几十个消息后主动调用空的InvokeAndWait(),这样保证屏幕不死掉。
    测试第三方API的响应速度,发现有些需要改进的地方。
5. javax.jms.JMSException: start failed: No buffer space available (maximum connections reached?): recv failed
    好像是连接不足,关掉一些网络程序后会好些,怀疑防火墙、sp2的连接限制(crack后好像没用)
 
其它:
    算法上的优化,不发送无用消息,减少不必要的数据库访问,尽量一次批量读取数据。

优化后的运行时间由分钟级别降到秒级,比较满意。
posted on 2005-11-25 18:32  steeven  阅读(4414)  评论(0编辑  收藏  举报