Java程序性能优化读书笔记(一)

作者: tcxurun 分类: Java 发布时间: 2015-03-24 22:29 ė 6 没有评论

一、常用优化组件和方法

1、缓冲

缓冲的一个典型应用是漏斗。
缓冲可以协调上层组件和下层组件的性能差,加快了上层组件的处理速度,从而提升系统的整体性能。
缓冲最常用的场景就是提高IO处理速度。

2、缓存

缓存(Cache)也是一块为提升系统性能而开辟的内层空间。缓存的主要作用是缓存数据处理结果,并提供下次访问使用。
缓存框架:EHCache、OSCache、JBossCache。

基于动态代理的缓存解决方案。

3、对象复用——“池”

对象池化,是目前非常常用的一种系统优化技术。它的核心思想是,如果一个类被频繁请求使用,那么不必每次都生成一个实例,可以将这个类的一些实例保存在一个“池”中,待需要使用的时候直接从池中获取。这个“池”就称为对象池。在实现细节上,它可能是一个数组,一个链表或者任何集合类。

在程序中使用数据库连接池和线程池,可以有效地改善系统在高并发下的性能。

线程池、数据库连接池(C3P0、Proxool)

Apache中,已经提供了一个Jakarata Commons Pool对象池组件。

4、并行代替串行

5、负载均衡
Tomcat集群

黏性Session Session信息平均分配,不具备高可用性
复制Session 所有的Session在所有Tomcat节点保持一致

专门用于分布式缓存框架——Terracotta,可与Jetty、Spring、EHCache集成使用

6、时间换空间

7、空间换时间

二、Java程序优化

1、字符串优化处理
①String对象及其特点
不变性、针对常量池的优化、类的final定义
针对常量池的优化指:当两个String对象拥有相同的值时,它们只引用常量池中的同一个拷贝。当同一个字符串反腐出现时,这个技术可以大幅度节省内存空间。

②subString()方法的内存泄漏
通过偏移量截取字符串,String的原生内容value数组被复制到新的字符串中。(阅读源码可以知道,这是以空间还时间策略)

③字符串分割和查找
StringTokenizer类效率更高、高效率的chatAt()方法

④StringBuffer和StringBuilder
静态字符串的连接操作,Java在编译时做了优化,变量字符串的累加也做了优化,与使用StringBuilder性能一样。
大量循环时,String连接操作性能远低于StringBuilder,对于String操作,类似于"+"和"+="运算符尽量少用。
String的concat()方法效率高于"+"和"+="运算符,但是又远远低于StringBuilder类。
非同步的StringBuilder效率高于同步的StringBuffer
合理设置容量参数

2、核心数据结构

  • List接口

ArrayList(线程不安全)与Vector(线程安全)都是数组实现的,随机访问快。
LinkedList是循环双向列表数据结构,随机访问性能很差。

  • Map接口

HashMap是线程不安全的,HashTable是线程安全的。LinkedHashMap:有序的,可按插入此书或访问顺序。TreeMap:基于元素的固有排序,内部实现基于红黑树(平衡二叉树)。

  • Set接口

元素不能重复
HashSet、LinkedHashSet、TreeSet都是对应的Map的一种封装。
RandomAccess接口是一个标志接口,其实现支持快速随机访问。

3、使用NIO提升性能
为所有的原始类型提供(Buffer)缓存支持
增加通道(channel)对象,作为新的原型I/O抽象

NIO的Buffer类族和Channel

Buffer的三个重要参数:位置(position)、容量(capacity)、上限(limit)
操作:复制缓冲区、缓冲区分片、只读缓冲区、文件映射到内存、处理结构化数据

4、引用类型

①强引用
强引用所指向的对象在任何时候都不会被系统回收,强引用可能导致内存泄漏。
②软引用
③弱引用
④虚引用
虚引用最大的作用在于跟踪对象回收,清理被销毁对象的相关资源。
⑤WeakHashMap类及其实现
WeakHashMap是HashMap的一种实现,它使用弱引用作为内部数据的存储方案。WeakHashMap作为弱引用的一个典型应用:它可以作为简单的缓存表解决方案。

5、有助于改善性能的技巧

(1)慎用异常
例:异常在循环内,就会给系统性能带来很大影响。

(2)使用局部变量
局部变量保存在栈中,速度较快,静态变量、实例变量都在堆中创建,速度较慢。

(3)位运算代替乘除法

(4)替换switch

(5)一维数组代替二维数组

(6)提取表达式

(7)展开循环

(8)布尔运算代替位运算
利用布尔运算的短路

(9)数组复制使用arrayCopy()
因为Systen.arrayCopy()函数是native函数,性能优于普通的函数。

(10)使用Buffer进行I/O操作
合理利用缓冲

(11)使用clone()代替new
注意深拷贝和浅拷贝

(12)用静态方法代替实例方法
工具类的使用

三、并行程序开发及优化

1、并行程序设计模式
(1)Future模式——类似于异步调用,Js中的回调函数。充分利用等待时间。

(2)Master-Worker模式
系统进程由两类进程协作工作:Master进程和Worker进程。Master进程负责接收和分配任务,Worker进程负责处理子任务。当各个Worker进程将子任务处理完成后,将结果返回给Master进程,由Master进程进行归纳和汇总,从而得到系统的最终结果。
Master-Worker模式是一种使用多线程进行数据处理的结构,多个Worker进程协作处理用户请求,Master进程负责维护Worker进程,并整合最终处理结果。

(3)Guarded Suspension模式
意为保护暂停,其核心思想是仅当服务进程准备好时,才提供服务。
有个请求队列充当缓存。
可以和Future模式结合。

(4)不变模式
注意不变模式和只读属性的区别
只读属性不能被其他线程修改,但自身状态可以修改。

(5)生产者——消费者模式
内存缓冲区的主要功能是数据在多线程间的共享,此外通过该缓冲区,可以缓解生产者和消费者之间的性能差。

可以看到许多方面都用到了缓冲技术

2、JDK多任务执行框架
(1)线程池

(2)Executor框架
任务队列:①直接提交的队列 ②有界的任务队列 ③无界的任务队列 ④优先任务队列
拒绝策略

(3)优化线程池大小
N(cpu) = CPU的数量
U(cpu) = 目标CPU的使用率 0 ≤ U(cpu) ≤ 1
W/C = 等待时间与计算时间的比率
最优线程池大小等于:
N(threads) = N(cpu) * U(cpu) * (1 + W/C)

四、JDK并发数据结构

1、并发List
Vector
CopyOnWriteArrayList:当对象进行写操作时,复制该对象,若进行读操作,则直接返回结果,操作过程中不进行同步。

2、并发Set
CopyOnWriteArraySet

3、并发Map
ConcurrentHashMap
性能优于同步的HashMap

4、并发Queue
①以ConcurrentLinkedQueue为代表的高性能队列
②以BlockingQueue接口(常用于多线程间的数据共享)为代表的阻塞队列。

有以下两种实现:

  • ArrayBlockingQueue:基于数组
  • LinkedBlockingQueue:基于链表

5、并发Deque
双端队列,允许在队列的头部或尾部进行出队、入队操作。

  1. LinkedList 线程不安全
  2. ArrayDeque 线程不安全
  3. LinkedBlockingDeque 线程安全,高并发应用中,性能远远低于LinkedBlockingQueue,更低于ConcurrentLinkedQueue。

五、并发控制方法

  1. Java内存模型与Volatite
  2. 同步关键字Synchronized
  3. ReentrantLock重入锁
  4. ReadWriteLock读写锁
  5. COndition对象
  6. Semaphore信号量
  7. ThreadLocal线程局部变量

六、“锁”的性能和优化

  1. 线程的开销
    如线程本身的元数据,线程的调度,线程上下文切换等。
  2. 避免死锁
    出现死锁需要满足一下条件:
    ①互斥条件
    ②请求与保持条件
    ③不剥夺条件
    ④循环等待条件
    只要打破死锁必要条件中的任意一个,就能解决死锁问题。
  3. 减小锁持有时间
  4. 减小锁粒度
  5. 读写锁分离来替换独占锁
  6. 锁分离
  7. 重入锁和内部锁 (推荐使用内部锁)
  8. 锁粗化
  9. 自旋锁
  10. 锁消除
    对锁的请求和释放是要消耗系统资源的,使用锁消除法术可以去掉那些不可能存在多线程访问的锁请求,从而提高系统性能。
  11. 锁偏向

七、无锁的并行计算

1、非阻塞的同步/无锁
2、原子操作
3、Amino框架
·集合 ·Set ·Amino树 ·Amino图 ·Amino简单调度模式

八、协程

1、协程是对线程的进一步分割,协程间的切换更为轻便。
2、Kilim框架
Task:协程的任务载体
Fibep:用于保存和管理任务的执行堆栈。
Mailbox:协程间的通信载体,用于数据共享和信息交流。

本文出自天一直很蓝,转载时请注明出处及相应链接。

本文永久链接: http://www.tcxurun.cn/archives/359

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Ɣ回顶部