性能概述
程序性能表现形式
- 执行速度:程序响应速度,总耗时是否足够短
- 内存分配:内存分配是否合理,是否过多消耗内存或者存在泄漏
- 启动时间:程序运行到可以正常处理业务需要的时间
- 负载承受能力
性能测评指标
- 执行时间
- CPU时间:函数或者线程占用CPU时间
- 内存分配:程序在运行时占用内存空间
- 磁盘吞吐量:描述I/O使用情况
- 络吞吐量:描述 络使用情况
- 响应时间:系统对用户行为或者时间做出回应的时间。
系统瓶颈相关计算机资源
- 磁盘I/O
- 络操作
- CPU
- 异常:对java来说,异常捕获和处理是非常消耗资源的
- 锁竞争:高并发程序中,锁的竞争对性能影响尤其重要,增加线程上下文切换开销。而且这部分开销与应用需求五官,占用CPU资源
- 内存:一般只要应用设计合理,内存读写速度不会太低,出发程序进行高频率内存交换扫描。
Amdahl定律
- Amdahl定义了串行系统并行化后加速比的计算公式和理论上线
- 加速比定义:加速比= 优化前系统耗时/优化后系统耗时
- Amdahl定律给出了加速比与系统并行°和处理器数量的关系,加速比Speedup,串行化程序比重F,CPU数量为N:
- Speedup
- 总结:根据Amdahl定律,使用多核CPU对系统进行优化,优化效果取决于CPU数量以及系统中串行程序比重,CPU数越多,串行比重越低优化效果更好。
性能调优层次
- 设计调优
- 代码调优
- JVM调优
- 数据库调优
- 操作系统优化
设计优化
善用设计模式
单例模式经典问题
- 用于长沙一个多小的具体实例,可以确保系统中一个类只产生一个实例,能带来两大好处:
- 对的频繁使用的对象,可以省略创建对象花费的时间,这对于那些重量级的对象而言,是非常可观的一笔系统开销
- 如上可见,没有使用instance,但是还是会新建,因此我们需要的是延迟加载机制,使用时候才创建,如下实现
- 如上,instance初始值null,在jvm加载时候没有额外的负担,需要调用getinstance()方法之后才会判断是否已经存在,不存在则加上锁来初始化。此处不加锁在并发情况会有线程安全问题。
- 以上案例用synchronized必然存在性能问题,存在锁竞争问题,如下改造
- 使用内部类来维护单例的实例,当StaticSingleton被加载时,内部类并不会被初始化,只有getInstance被调用才会加载SingletionHolder,从而初始化instance,因为实例的建立是类加载完成,所以天生就对多线程友好。
- CGLIB的动态代理使用和JDK的类似,如上代码。
- Javassist的动态java代码创建代理过程和上面的有一些不同,javassist内部可以通过动态java代码,生成字节码,这种方式创建的动态代理可以非常灵活,甚至可以在运行时候生成业务逻辑。很奇特的一种用法,如下代码:
代理模式
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!