性能优化总结:
一个任务对数据库频繁操作,并且大量发送消息。时间暴长!
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后好像没用)
其它:
算法上的优化,不发送无用消息,减少不必要的数据库访问,尽量一次批量读取数据。
优化后的运行时间由分钟级别降到秒级,比较满意。
Java学习开发三件宝: Domain Model(域建模)、Patterns(模式)和Framework(框架)。
集三宝理念于一身,小中型J2EE项目快速开发工具:Jdon Framework
阅读(1123) | 评论(0) | 转发(0) |