- 关于Java优化
集合的选择
String、StringBuffer、StringBuilder
String、StringBuffer、StringBuilder都是采用char数组实现的
StringBuffer、StringBuilder默认初始化16个
扩容int newCapacity = (value.length + 1) * 2;
1,Vector、Hashtable、Stack(Collections. synchronizedList)
2,减少I/O访问(缓存)
3, 读写分开(分盘)
4, 线程同步块
5,单例模式实现缓存(Map)
//伪代码(采用单例模式实现缓存)
class Cache {
private Map map;
private static Cache instance = new Cache();
private Cache() {}
public static Cache getInstance() {
return instance;
}
public synchronized getObject(String className) {
if (map.containts(className)) {
return map.get(className);
}else {
Object instance = Class.forName(className).newInstance();
map.put(className, instance);
}
}
}
- 数据库优化
1,数据库表设计优化,建表时加入冗余字段,减少关联查询
2, 尽量使用PrepareStatement,减少编译次数,提高效率(SQL语句也需要先编译再执行)
3, Connection设置为readOnly,表示启动只读模式,启动数据库的优化策略。
4, 在jdbc中采用批量
5, 索引优化,对常查询的字段建立索引
6, 尽量减少嵌套查询(select(select(select)))
7, 尽量减少group和having子句的应用
8, 利用视图
9, 采用数据库机制进行分页查询,提高性能,尽量使用物理分页(和物理分页相对的还有逻辑分页)
10, 调整连接池中的连接数量和等待时间,调整数据库本身对Connection数量的支持
11,Mysql默认为100个Connection(my.ini)
12,Oracle 10G默认是150个Connection(F:\oracle\product\10.2.0\admin\bjpowernode\pfile\ init.ora)
13,引入连接池(最小连接数、最大连接数、最大等待时间、最大空闲时间等)
14,配置项为:
15,
16,30
17,
18,50 - 中间件(Tomcat、Weblogic、Jboss)优化
1, 调整中间件虚拟机内存(堆内存、栈内存)
2, 调整线程数
3, 在运行环境下(生产环境下)屏蔽控制台日志的输出 js优化
a) 压缩
b) js文件加载位置
1, input输入可以设置为disabled
2, 页面静态化
a) 真静态,一般采用CMS(内容管理系统)系统完成
b) 伪静态
1, No SQL(非关系型数据库),海量数据(使用非关系型数据库存储数据,例如Facebook)
2, 二分法(建立在排序基础上)
3, Comparable和Comparator,优先考虑Comparator,体现了策略模式分页查询用户信息的优化
1, 表关联查询,查询用户信息的时候关联查询机构信息,此时的延迟加载失效,发送一条语句直接全部取得(from User u join fetch u.org)
2, 取用户信息的时候连同机构的信息一并取出(调整抓取策略)- Hibernate优化问题
1, 合理使用延迟加载
2, 选择session.load() 使用代理机制(cglib动态代理,cglib存在bug,hibernate3.3以上使用了jboss公司的javassist)
3, 选择session.get()
4, 抓取策略(一次全部取出,避免N+1)
5, 在HQL语句中使用抓取连接查询,通过写一条left join fetch 语句把相关联的两个实体的数据一次性从数据库中加载上来。这样可以在特定情况下(同时需要使用到这两个实体的数据)减少SQL的数量来提高查询效率
6, Query.iterate()和Query.list()的选择
Query.iterate{
1:select id from Student s
N:select s from Stuent where s.id=?
}
支持从一级缓存和二级缓存中取数据,但是可能导致N+1问题,假如缓存中没有数据,iterate方法会发送一条SQL将所有数据的id查询出来放到缓存中,当迭代使用对象的时候会再发送N条SQL语句根据id查询对象。不过已查询出的对象会被放入一级缓存和二级缓存中,当第二次再访问该对象的时候会直接从缓存中取。
Query.list {
select s from Student s;
}
不支持从一级缓存和二级缓存中取数据,但是查询结果会被放入一级缓存和二级缓存中,每一次查询都会从数据库中,除非使用了查询缓存,使用了查询缓存,list方法会从查询缓存中取数据。
1, 缓存管理
2, 一级缓存(Session cache)生命周期和Session相同,存储对象
3, Session级别的缓存由hibernate自动管理。当应用程序调用Session的CRUD方法及调用查询接口的list(),iterate()等方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把改对象加入到Session缓存中。如果在Session缓存中已经存在这个对象,就不需要再去数据库加载而是直接使用缓存中的这个对象,可以减少访问数据库的频率,提高程序的运行效率。当Hibernate清理缓存时(默认是提交事务的时候),Hibernate会根据缓存中对象的状态来同步数据库中的数据状态,在关闭Session时,会清空Session缓存中的所有对象。一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict(Object obj):从缓存中清除指定的持久化对象。clear():清空缓存中所有持久化对象。flush(): 进行清理缓存(此时缓存中的数据并不丢失)的操作,让缓存和数据库同步 执行一些列sql语句,但不提交事务。commit():先调用flush() 方法,然后提交事务. 则意味着提交事务意味着对数据库操作永久保存下来。当做批量插入或批量更新时,必须通过经常调用Session的flush()以及稍后调用clear()来控制一级缓存的大小,这样内存才能保证足够的空间。
4, 二级缓存(SessionFactory cache)生命周期和SessionFactory相同,存储对象
5, 执行条件查询的时候,发出“select * from table_name where …”这样的SQL语句查询数据库,一次获得所有的数据对象。把获得的所有数据对象根据ID放入到二级缓存中。当Hibernate根据ID访问数据对象时,首先从Session缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;还没查到,再查询数据库,把结果按照ID放入到二级缓存。删除、更新和增加数据的时候,同时会更新到二级缓存中。Hibernate的二级缓存策略是针对ID查询的缓存策略,对于调节查询则毫无作用。为此,hibernate提高了单独针对条件查询的查询缓存。适合存放到二级缓存中的数据有:很少被修改的数据。不是很重要的数据,允许出现偶尔的并发的数据。很多系统模块都要用到不是私有的数据,是共享的什么样的数据不适合放在二级缓存中???财务数据 安全性的数据 也就是不想让别人看到的数据和特别重要的数据
6, 查询缓存(Query cache)存储对象的普通属性、对象id,当查询缓存关联的表中数据发生变动时查询缓存消失,当使用查询缓存之后,query.list()会从query cache中取数据,减少SQL语句的发送。
7, 控制SQL语句的发出粒度(i/o)(查询数据,数据量庞大最好分页查询,调整每页显示的数量)
8, 拼装HQL最好使用问号方式
9, 配置inservse/mappedBy