笔记《Java程序性能优化 让你的Java程序更快、更稳定》 第二章 设计调优

9/6/2015来源:Java教程人气:1573

笔记《java程序性能优化 让你的Java程序更快、更稳定》 第二章 设计调优

2.1 善用设计模式 23 (1)

1. 设计模式好处;

clip_image001[6]

2.1.1 单例模式 23 (6)

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

2. 两大好处:a、对于频繁创建的对象,可以省略创建对象所花费的时间;b、new操作减少,因而对系统内存的使用频率也会降低,降低GC压力,缩短GC停顿时间;

3. 单例模式的参与者:单例类和使用者;

4. 第一种实现方式:私有默认构造器,静态getInstance方法;这种实现方式简单、可靠,但不能延迟加载;

5. 第二种实现方式:私有默认构造器,创建时判断对象是否为空,提供同步的getInstance方法;这种实现方式虽然能够延迟加载,但引入了同步,多线程时时耗远远大于第一种实现;

6. 第三种实现方式:私有默认构造器,私有静态内部类里边创建私有静态的实例,静态getInstance方法;当getInstance被调用时,才会加载SingletonHolder,从而初始化instance,同时,由于实例的建立是在类加载时完成的,故天生对多线程友好;

clip_image003

clip_image005[6]

第一种实现:

clip_image007[6]

这种单例的实现方式简单、有效,但是不能延迟加载;

clip_image009[6]

clip_image011[6]

clip_image013

第二种实现方式,引入延迟加载:

clip_image015

clip_image017

clip_image019

第三种实现方式:

clip_image021

clip_image023

clip_image025

clip_image027

clip_image029

clip_image031

clip_image033

clip_image035

2.1.2 代理模式 28 (17)

1. 使用代理对象完成用户请求,屏蔽用户对真实对象的访问;

2. 使用代理模式的意图:安全原因、远程调用、延迟加载(提升系统的性能和反应速度);

3. 代理模式的主要参与者:主题接口、真实主题、代理类、客户端;

4. 延迟加载的常用案例:数据库连接、系统启动,hibernate框架;

5. 延迟加载的核心思想:如果当前并没有使用该组件,则不需要真正地初始化它,使用一个代理对象替代它原有的位置,只要在真正需要使用的时候,才对它进行加载;

6. 动态代理是指在运行时,动态生成代理类;

7. 和静态代理相比,动态代理的好处:1、不需要为真实主题写一个形式上完全一样的封装类,2、使用一些动态代理的生成方法甚至可以在运行时指定代理类的执行逻辑;

8. 生成动态代理类的方法有4种:JDK自带的动态代理、CGLIB、javassist、ASM库;

9. JDK自带的动态代理使用简单,但功能较弱;

10. CGLIB和javassist是高级的字节码生成库,性能比JDK自带的好,且功能强大;

11. ASM库低级的字节码生成工具,对开发人员要求较高,性能没有量级的提升,可维护性差,只在性能要求苛刻的地方使用;

12. JDK的动态代理实现:实现InvocationHandler接口,通过PRoxy.newProxyInstance方法创建代理;

13. CGLIB的实现(javassist类似):实现MethodInterceptor接口,new Enhancer-->setCallback-->setInterfaces-->create;

14. javassist有两种方式创建:1、使用代理工厂;2、通过使用动态代码创建;

15. javassist代理工厂方式实现:实现MethodInterceptor接口,new ProxyFactory-->setInterfaces-->createClass-->newInstance;

16. javassist使用动态代码方式创建,相当灵活,甚至可以在运行时生成业务逻辑;

17. javassist动态代码方式实现:ClassPool,CtClass;

clip_image037

clip_image039

clip_image041

clip_image043

clip_image045

clip_image047

clip_image049

clip_image051

jdk的动态代理实现:

clip_image053

clip_image055

clip_image057

CGLIB的实现:

clip_image059

clip_image061

javassist的代理工厂实现:

clip_image063

clip_image065

javassist动态java代码方式实现:

clip_image067

clip_image069

几种实现方式性能测试:

clip_image071

clip_image073

clip_image075

clip_image077

2.1.3 亨元模式 37 (8)

1. 亨元模式以提高系统性能为目的,核心思想是如果一个系统中存在多个相同的对象,那么只需共享一份对象的拷贝,而不必每次都创建新的对象。

2. 亨元模式对性能提升的主要帮助有两点:(1)、可以节省重复创建对象的开销,(2)、由于创建对象的数量减少,所以对内存的需求也减少,GC压力降低;

3. 亨元模式的主要角色有4个:亨元工厂、抽象亨元、具体亨元类和主函数;

4. 一般情况下,亨元工厂会维护一个对象列表,如果请求的对象已经创建,则直接返回,如果没有,则创建对象加入到维护队列中;

5. 亨元模式的典型应用:SAAS系统(Software As A Service,目前比较流行的一种软件应用模式);

6. 以一个人事管理系统的SAAS系统为例,公司甲、乙、丙都为这个SAAS系统的用户,则3个亨元实例,就足以应付300个员工的查询请求了;

7. 亨元模式和对象池的最大不同是亨元模式的对象都是不可以相互替代的,对象池的对象都是等价的,如数据库连接池中的数据库连接;

8. 报表实例;

clip_image079

clip_image081

clip_image083

clip_image085

clip_image087

clip_image089

实例:

clip_image091

clip_image093

clip_image095

clip_image097

clip_image099

clip_image101

clip_image103

2.1.4 装饰者模式 40 (7)

1. 装饰者模式可以动态添加对象功能;

2. 有一条重要的设计准则叫做合成/聚合复用原则:代码复用应该尽可能使用委托,而不是使用继承;因为继承是一种紧密耦合,任何父类的改动都会影响其子类,不利于系统维护。而委托则是松散耦合,只要接口不变,委托类的改动并不会影响其上层对象;

3. 装饰者模式通过委托机制,复用系统中的各个组件,在运行时,可以将这些功能组件进行叠加,从而构造一个“超级对象”,使其拥有所有这些组件的功能;

4. 装饰者模式的好处:可以有效地分离性能组件和功能组件,从而提升模块的可维护性并增加模块的复用性;

5. 装饰者模式的主要角色有4个:组件接口、具体组件、装饰者、具体装饰者;

6. 装饰者的典型案例是对输出结果进行增强,对输出内容转化为HTML,增加HTTP头;

7. JDK中不少组件用装饰者模式实现,比如OutputStream和InputStream类族的实现;

clip_image105

clip_image107

clip_image109

案例:

clip_image111

clip_image113

clip_image115

clip_image117

clip_image119

clip_image121

clip_image123

clip_image125

clip_image127

clip_image129

jdk中的不少组件用装饰者模实现;

clip_image131

clip_image133

clip_image135

clip_image137

clip_image139

clip_image141

clip_image143

2.1.5 观察者模式 46 (5)

1. 当一个对象的行为依赖于另一个对象的状态时,适用于观察者模式,如果不用,则一般需要在另一个线程中不停监听对象所依赖的状态,增加系统的负担;

2. 观察者模式的意义在于:可以在单线程中,使某一个对象,及时得知自身所依赖的状态变化。

3. 观察者模式可以用于事件监听、通知发布等场合;

4. 观察者模式的主要角色有4个:主题接口、具体主题、观察者接口、具体观察者;

5. JDK有一套观察者模式的实现,java.util.Observable类和java.util.Observer接口,

clip_image145

clip_image147

clip_image149

实例:

clip_image151

clip_image153

clip_image155

clip_image157

clip_image159

clip_image161

clip_image163

2.1.6 Value Object模式 50 (2)

1. 在J2EE软件开发中,通常会对系统模块进行分层;

2. Value Object模式提倡将一个对象的各个属性进行封装,将封装后的对象在网络中传递,从而拥有更好的交互模型,并且减少网络通信数据,从而提高系统性能;

clip_image165

clip_image167

clip_image169

2.1.7 业务代理模式 53 (2)

1. 业务代理模式是将一组由远程方法调用构成的业务流程,封装在一个位于展示层的代理中;

2. 业务代理模式将一些业务流程封装在前后台系统,为系统性能优化提供了基础平台,在业务代理中,不仅可以复用业务流程,还可以视情况为展示层组件提供缓存等功能,从而减少远程方法调用次数,降低系统压力;

clip_image171

clip_image173

clip_image175

clip_image177

clip_image179

clip_image181

clip_image183

clip_image185

2.2 常用优化组件和方法 56 (2)

1. 组件:缓冲和缓存;

2. 常用的5个优化思想:池化对象、并行代替串行、负载均衡、时间换空间、空间换时间;

2.2.1 缓冲(Buffer) 56 (6)

1. 缓冲区是一块特定的内存区域;

2. 开辟缓冲区的目的是缓解应用程序上下层之间的性能差异,提高系统的性能。

3. 日常生活中,缓冲区的一个典型应用是漏斗;

4. 缓冲可以协调上层组件和下层组件的性能差,当上层组件性能优于下层组件时,可以有效较少上层组件对下层组件的等待时间;

5. 缓冲最常用的场景就是提高I/O的速度;

6. 案例:使用缓冲区提升动画显示效果(先在内存中画圆,然后一次性显示出来);

clip_image187

clip_image189

clip_image191

clip_image193

clip_image195

clip_image197

clip_image199

案例:使用缓冲区提升动画显示效果

clip_image201

clip_image203

clip_image205