Java性能优化

性能调优的层次

  1. 设计调优
  2. 代码调优
  3. JVM调优
  4. 数据库调优
  5. 操作系统调优

设计调优

善用设计模式

单例模式

单例模式是一种对象的创建模式,用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。好处;

1> 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销

2> 确保一个类只有一个对象,每次调用都是同一个对象,减少new的操作次数,降低对系统的内存的使用频率,减轻GC压力,缩短GC停顿时间

代理模式

将消耗资源最多的方法都使用代理模式分离,就可以加快系统的启动速度,减少用户的等待时间。

核心其实就是使用延迟加载,只有当用到了当前的组件时,才会去初始化他。这样如果有些组件没有被用到,就不用加载,避免资源的浪费

享元模式

如果一个系统中存在多个相同的对象,那么只需共享一份对象拷贝,而不必为每次使用都创建新的对象,好处:

1> 被享元模式维护的相同对象每次只会被创建一次,当创建的对象比较耗时时,便可以节省大量时间

2> 创建对象减少,内存的需求也会减少,使得GC的压力也响应降低

应用:String类对象,Java中将String类定义为final(不可改变的),JVM中字符串一般保存在字符串常量池中,java会确保一个字符串在常量池中只有一个拷贝,这个字符串常量池在JDK6.0以前是位于常量池中,位于永久代,而在JDK7.0中,JVM将其从永久代拿出来放置于堆中

观察者模式

当一个对象的行为依赖于另外一个对象的状态时,观察者模式就相当有用,如果不使用观察者模式,则只能在另一个线程中不停的监听对象所依赖的状态。可能需要开很多线程来实现这个功能

常用优化组件和方法

1、缓冲
缓冲区可以是一块特定的区域,主要是为了解决应用程序上下层之间的性能差异,提高系统的性能。使用场景特点:

1> 数据通信不需要太实时,异步通信

应用:消息队列MQ,起到削峰填谷的功能。日志系统silfj,数据太大就先写入队列,慢慢写入日志服务器

2、缓存
作用:开辟一块内存空间存放数据处理结果,供下次访问使用。

应用:Redis等缓存软件功能

3、对象复用(池化)
如果一个类被频繁请求使用,那么不必每次都生成一个实例,可以将这个类的一些实例保存在一个池中,待需要使用时从池中获取,用完了再放回池中。

应用:线程池和数据库的连接池都是使用了该方法

4、并行代替串行
结合CPU的多核并行能力,开启多线程发挥CPU的最大潜能

5、负载均衡
应用:分布式集群

Java程序优化

有助于提升性能的技巧
1、慎用异常
try-catch实现:每个类class文件会跟随一张异常表,每一个try-catch都会在这个表里添加行记录,每一个记录都有4个信息(try catch的开始行(begin_pc),结束行(begin_pc),异常的处理起始行(handler_pc,catch代码块),异常类型catch_type)

1> 代码发生异常时,就会去异常表中找抛出异常的行是否在begin_pc和begin_end之间,如果是的话,并且是catch_type类型,则跳转到handler_pc的位置去执行。停止方法的出栈、入栈操作,回溯出整个链路的栈信息

2> 如果代码不发生异常,则不会去表中查找,基本上不会有性能消耗
建议:需要try-catch的地方还是需要继续用。避免在for循环中使用

2、使用局部变量
调用方法时传参以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,静态变量,实例变量等,都在堆(Heap)中创建,速度较慢

3、位运算代替乘除法
所有运算中,位运算是最高效的

a*=2 ==> a<<=1

a/=2 ==> a>>=1

4、尽可能的提取表达式,避免多余的计算
x = d a b / 3 4 a;

y = e a b / 3 4 a;

可以优化为

t = a b / 3 4 * a;

x = d * t;

y = e * t;

5、静态方法替代实例方法
java中实例方法需要维护一张类似虚函数表的结构,以实现对多态的支持。与静态方法相比,实例方法的调用需要更多的资源(比如如果它继承了父类的话,实例化对象时可能需要执行父类的构造方法)

你可能感兴趣的