Java程序性能优化 让你的Java程序更快 更稳定pdf

图书网 2018年10月19日23:11:16
评论
2.3K
摘要

数千读者好评,上万读者的选择,数万Java爱好者和程序员受益匪浅!
一个优秀的程序员,不仅要会编写程序,更要会编写高质量的程序
感受Java开发中的大智慧,让你的Java程序更优美
专注于Java应用程序的优化方法、技巧和思想
深入剖析软件设计层面、代码层面、JVM虚拟机层面的优化方法
理论结合实际,使用丰富的示例帮助读者理解理论知识

Java程序性能优化 让你的Java程序更快 更稳定 内容简介

Java是目前应用为广泛的软件开发平台,学习针对Java程序的优化方法有重要的现实意义。《Java程序性能优化:让你的Java程序更快、更稳定》以Java性能调优为主线,系统地阐述了与Java性能优化相关的知识与技巧。

《Java程序性能优化:让你的Java程序更快、更稳定》共6章,先后从软件设计、软件编码、JVM调优以及程序故障排斥等方面介绍针对Java程序的优化方法。第1章介绍性能的基本概念、定律、系统调优的过程和注意事项。第2章从设计层面介绍与性能相关的设计模式、组件。第3章从代码层面介绍如何编写高性能的Java程序。第4章介绍了并行开发和如何通过多线程提高系统性能。第5章立足于JVM虚拟机层面,介绍如何通过设置合理的JVM参数提升Java程序的性能。第6章为工具篇,介绍了获取和监控程序或系统性能指标的各种工具,包括相关的故障排查工具。

《Java程序性能优化:让你的Java程序更快、更稳定》适合所有Java程序员、软件设计师、架构师以及软件开发爱好者,对于有一定经验的Java工程师,本书更能帮助他突破技术瓶颈,深入Java内核开发!

Java程序性能优化 让你的Java程序更快 更稳定 目录

第1章 Java性能调优概述

1.1 性能概述

1.1.1 看懂程序的性能

1.1.2 性能的参考指标

1.1.3 木桶原理与性能瓶颈

1.1.4 Amdahl定律

1.2 性能调优的层次

1.2.1 设计调优

1.2.2 代码调优

1.2.3 JVM调优

1.2.4 数据库调优

1.2.5 操作系统调优

1.3 基本调优策略和手段

1.3.1 优化的一般步骤

1.3.2 系统优化注意事项

1.4 小结

第2章 设计优化

2.1 善用设计模式

2.1.1 单例模式

2.1.2 代理模式

2.1.3 享元模式

2.1.4 装饰者模式

2.1.5 观察者模式

2.1.6 Value Object模式

2.1.7 业务代理模式

2.2 常用优化组件和方法

2.2.1 缓冲(Buffer)

2.2.2 缓存(Cache)

2.2.3 对象复用——“池”

2.2.4 并行替代串行

2.2.5 负载均衡

2.2.6 时间换空间

2.2.7 空间换时间

2.3 小结

第3章 Java程序优化

3.1 字符串优化处理

3.1.1 String对象及其特点

3.1.2 subString()方法的内存泄漏

3.1.3 字符串分割和查找

3.1.4 StringBuffer和StringBuilder

3.2 核心数据结构

3.2.1 List接口

3.2.2 Map接口

3.2.3 Set接口

3.2.4 优化集合访问代码

3.2.5 RandomAccess接口

3.3 使用NIO提升性能

3.3.1 NIO的Buffer类族和Channel

3.3.2 Buffer的基本原理

3.3.3 Buffer的相关操作

3.3.4 MappedByteBuffer性能评估

3.3.5 直接内存访问

3.4 引用类型

3.4.1 强引用

3.4.2 软引用

3.4.3 弱引用

3.4.4 虚引用

3.4.5 WeakHashMap类及其实现

3.5 有助于改善性能的技巧

3.5.1 慎用异常

3.5.2 使用局部变量

3.5.3 位运算代替乘除法

3.5.4 替换switch

3.5.5 一维数组代替二维数组

3.5.6 提取表达式

3.5.7 展开循环

3.5.8 布尔运算代替位运算

3.5.9 使用arrayCopy ()

3.5.10 使用Buffer进行I/O操作

3.5.11 使用clone()代替new

3.5.12 静态方法替代实例方法

3.6 小结

第4章 并行程序开发及优化

4.1 并行程序设计模式

4.1.1 Future模式

4.1.2 Master-Worker模式

4.1.3 Guarded Suspension模式

4.1.4 不变模式

4.1.5 生产者-消费者模式

4.2 JDK多任务执行框架

4.2.1 无限制线程的缺陷

4.2.2 简单的线程池实现

4.2.3 Executor框架

4.2.4 自定义线程池

4.2.5 优化线程池大小

4.2.6 扩展ThreadPoolExecutor

4.3 JDK并发数据结构

4.3.1 并发List

4.3.2 并发Set

4.3.3 并发Map

4.3.4 并发Queue

4.3.5 并发Deque

4.4 并发控制方法

4.4.1 Java内存模型与volatile

4.4.2 同步关键字synchronized

4.4.3 ReentrantLock重入锁

4.4.4 ReadWriteLock读写锁

4.4.5 Condition对象

4.4.6 Semaphore信号量

4.4.7 ThreadLocal线程局部变量

4.5 “锁”的性能和优化

4.5.1 线程的开销

4.5.2 避免死锁

4.5.3 减小锁持有时间

4.5.4 减小锁粒度

4.5.5 读写分离锁来替换独占锁

4.5.6 锁分离

4.5.7 重入锁ReentrantLock和内部锁synchronized

4.5.8 锁粗化(Lock Coarsening)

4.5.9 自旋锁(Spinning Lock)

4.5.10 锁消除(Lock Elimination)

4.5.11 锁偏向(Biased Lock)

4.6 无锁的并行计算

4.6.1 非阻塞的同步/无锁

4.6.2 原子操作

4.6.3 Amino框架介绍

4.6.4 Amino集合

4.6.5 Amino树

4.6.6 Amino图

4.6.7 Amino简单调度模式

4.7 协程

4.7.1 协程的概念

4.7.2 Kilim框架简介

4.7.3 Task及其状态

4.7.4 Fiber及其状态

4.7.5 Kilim开发环境配置

4.7.6 Kilim之Hello World

4.7.7 多任务通信

4.7.8 Kilim实例及性能评估

4.8 小结

第5章 JVM调优

5.1 Java虚拟机内存模型

5.1.1 程序计数器

5.1.2 Java虚拟机栈

5.1.3 本地方法栈

5.1.4 Java堆

5.1.5 方法区

5.2 JVM内存分配参数

5.2.1 设置最大堆内存

5.2.2 设置最小堆内存

5.2.3 设置新生代

5.2.4 设置持久代

5.2.5 设置线程桟

5.2.6 堆的比例分配

5.2.7 堆分配参数总结

5.3 垃圾收集基础

5.3.1 垃圾收集的作用

5.3.2 垃圾回收算法与思想

5.3.3 垃圾收集器的类型

5.3.4 评价GC策略的指标

5.3.5 新生代串行收集器

5.3.6 老年代串行收集器

5.3.7 并行收集器

5.3.8 新生代并行回收(Parallel Scavenge)收集器

5.3.9 老年代并行回收收集器

5.3.10 CMS收集器

5.3.11 G1收集器(Garbage First)

5.3.12 Stop the World案例

5.3.13 收集器对系统性能的影响

5.3.14 GC相关参数总结

5.4 常用调优案例和方法

5.4.1 将新对象预留在新生代

5.4.2 大对象进入老年代

5.4.3 设置对象进入老年代的年龄

5.4.4 稳定与震荡的堆大小

5.4.5 吞吐量优先案例

5.4.6 使用大页案例

5.4.7 降低停顿案例

5.5 实用JVM参数

5.5.1 JIT编译参数

5.5.2 堆快照(堆Dump)

5.5.3 错误处理

5.5.4 取得GC信息

5.5.5 类和对象跟踪

5.5.6 控制GC

5.5.7 选择类校验器

5.5.8 Solaris下线程控制

5.5.9 使用大页

5.5.10 压缩指针

5.6 实战JVM调优

5.6.1 Tomcat简介与启动加速

5.6.2 Web应用程序介绍

5.6.3 JMeter介绍与使用

5.6.4 调优前Web应用运行状况

5.6.5 调优过程

5.7 总结

第6章 Java性能调优工具

6.1 Linux命令行工具

6.1.1 top命令

6.1.2 sar命令

6.1.3 vmstat命令

6.1.4 iostat命令

6.1.5 pidstat工具

6.2 Windows工具

6.2.1 任务管理器

6.2.2 perfmon性能监控工具

6.2.3 Process Explorer

6.2.4 pslist命令行

6.3 JDK命令行工具

6.3.1 jps命令

6.3.2 jstat命令

6.3.3 jinfo命令

6.3.4 jmap命令

6.3.5 jhat命令

6.3.6 jstack命令

6.3.7 jstatd命令

6.3.8 hprof工具

6.4 JConsole工具

6.4.1 JConsole连接Java程序

6.4.2 Java程序概况

6.4.3 内存监控

6.4.4 线程监控

6.4.5 类加载情况

6.4.6 虚拟机信息

6.4.7 MBean管理

6.4.8 使用插件

6.5 Visual VM多合一工具

6.5.1 Visual VM连接应用程序

6.5.2 监控应用程序概况

6.5.3 Thread Dump和分析

6.5.4 性能分析

6.5.5 快照

6.5.6 内存快照分析

6.5.7 MBean管理

6.5.8 TDA使用

6.5.9 BTrace介绍

6.6 Visual VM对OQL的支持

6.6.1 Visual VM的OQL基本语法

6.6.2 内置heap对象

6.6.3 对象函数

6.6.4 集合/统计函数

6.6.5 程序化OQL

6.7 MAT内存分析工具

6.7.1 初识MAT

6.7.2 浅堆和深堆

6.7.3 支配树(Dominator Tree)

6.7.4 垃圾回收根

6.7.5 内存泄露检测

6.7.6 最大对象报告

6.7.7 查找支配者

6.7.8 线程分析

6.7.9 集合使用情况分析

6.7.10 扩展MAT

6.8 MAT对OQL的支持

6.8.1 Select子句

6.8.2 From子句

6.8.3 Where子句

6.8.4 内置对象与方法

6.9 JProfile简介

6.9.1 JProfile使用配置

6.9.2 内存视图

6.9.3 堆快照

6.9.4 CPU视图

6.9.5 线程视图

6.9.6 JVM统计信息

6.9.7 触发器

6.10 小结

Java程序性能优化 让你的Java程序更快 更稳定 精彩文摘

第1章 Java性能调优概述

本章对性能优化技术进行整体性的介绍,让读者了解性能的概念和性能优化的基本思路与方法。掌握这些内容,有助于读者对性能问题进行系统性的分析。

本章涉及的主要知识点有:

*评价性能的主要指标;

*木桶原理的概念及其在性能优化中的应用;

*Amdahl定律的含义;

*性能调优的层次;

*系统优化的一般步骤和注意事项。

1.1性能概述

为什么程序总是那么慢?它现在到底在干什么?时间都花到哪里去了?也许,你经常会抱怨这些问题。如果是这样,那说明你的程序出了性能问题。和功能性问题相比,性能问题在有些情况下,可能并不算什么太大的问题,将就将就,也就过去了。但是,严重的性能问题会导致程序瘫痪、假死,直至奔溃。本节就先来认识性能的各种表现和指标。

1.1.1看懂程序的性能

对客户端程序而言,拙劣的性能会严重影响用户体验。界面停顿、抖动、响应迟钝等问题会遭到用户不停的抱怨。一个典型的例子就是EclipseIDE工具在FullGC时会出现程序假死现象,相信一定被不少开发人员所诟病。对于服务器程序来说,性能问题则更为重要,相信不少后台服务器软件都有各自的性能目标。以Web服务器为例,服务器的响应时间、吞吐量就是两个重要的性能参数。当服务器承受巨大的访问压力时,可能出现响应时间变长、吞吐量下降,甚至是抛出内存溢出异常而崩溃。这些问题,都是性能调优需要解决的。

一般来说,程序的性能通过以下几个方面来表现:

*执行速度:程序的反映是否迅速,响应时间是否足够短。

*内存分配:内存分配是否合理,是否过多地消耗内存或者存在泄漏。

*启动时间:程序从运行到可以正常处理业务需要花费多长时间。

*负载承受能力:当系统压力上升时,系统的执行速度、响应时间的上升曲线是否平缓。

1.1.2性能的参考指标

为了能够科学地进行性能分析,对性能指标进行定量评测是非常重要的。目前,一些可以用于定量评测的性能指标有:

*执行时间:一段代码从开始运行到运行结束,所使用的时间。

*CPU时间:函数或者线程占用CPU的时间。

*内存分配:程序在运行时占用的内存空间。

*磁盘吞吐量:描述I/O的使用情况。

*网络吞吐量:描述网络的使用情况。

*响应时间:系统对某用户行为或者事件做出响应的时间。响应时间越短,性能越好。

1.1.3木桶原理与性能瓶颈

木桶原理又称“短板理论”,其核心思想是:一只木桶盛水的多少,并不取决于桶壁上最高的那块木块,而是取决于桶壁上最短的那块,如图1.1所示。

图1.1木桶原理示意图

将这个理论应用到系统性能优化上,可以这么理解,即使系统拥有充足的内存资源和CPU资源,但是如果磁盘I/O性能低下,那么系统的总体性能是取决于当前最慢的磁盘I/O速度,而不是当前最优越的CPU或者内存。在这种情况下,如果需要进一步提升系统性能,优化内存或者CPU资源是毫无用处的。只有提高磁盘I/O性能才能对系统的整体性能进行优化。而此时,磁盘I/O就是系统的性能瓶颈。

·注意:根据木桶原理,系统的最终性能取决于系统中性能表现最差的组件。因此,为了提升系统整体性能,必须对系统中表现最差的组件进行优化,而不是对系统中表现良好的组件进行优化。

根据应用的特点不同,任何计算机资源都有可能成为系统瓶颈。其中,最有可能成为系统瓶颈的计算资源如下。

*磁盘I/O:由于磁盘I/O读写的速度要比内存慢很多,程序在运行过程中,如果需要等待磁盘I/O完成,那么低效的I/O操作会拖累整个系统。

*网络操作:对网络数据进行读写的情况与磁盘I/O类似。由于网络环境的不确定性,尤其是对互联网上数据的读写,网络操作的速度可能比本地磁盘I/O更慢。因此,如不加特殊处理,也极可能成为系统瓶颈。

*CPU:对计算资源要求较高的应用,由于其长时间、不间断地大量占用CPU资源,那么对CPU的争夺将导致性能问题。如科学计算、3D渲染等对CPU需求旺盛的应用。

*异常:对Java应用来说,异常的捕获和处理是非常消耗资源的。如果程序高频率地进行异常处理,则整体性能便会有明显下降。

*数据库:大部分应用程序都离不开数据库,而海量数据的读写操作可能是相当费时的。而应用程序可能需要等待数据库操作完成或者返回请求的结果集,那么缓慢的同步操作将成为系统瓶颈。

*锁竞争:对高并发程序来说,如果存在激烈的锁竞争,无疑是对性能极大的打击。锁竞争将会明显增加线程上下文切换的开销。而且,这些开销都是与应用需求无关的系统开销,白白占用宝贵的CPU资源,却不带来任何好处。

*内存:一般来说,只要应用程序设计合理,内存在读写速度上不太可能成为性能瓶颈。除非应用程序进行了高频率的内存交换和扫描,但这些情况比较少见。使内存制约系统性能的最可能的情况是内存大小不足。与磁盘相比,内存的大小似乎小的可怜,这意味着应用软件只能尽可能将常用的核心数据读入内存,这在一定程度上降低了系统性能。

1.1.4Amdahl定律

Amdahl定律是计算机科学中非常重要的定律,它定义了串行系统并行化后加速比的计算公式和理论上限。

加速比定义:加速比=优化前系统耗时/优化后系统耗时

所谓加速比,就是优化前的耗时与优化后耗时的比值。加速比越高,表明优化效果越明显。

Amdahl定律给出了加速比与系统并行度和处理器数量的关系。设加速比为Speedup,系统内必须串行化的程序比重为F,CPU处理器数量为N,则有:

根据这个公式,如果CPU处理器数量趋于无穷,那么加速比与系统的串行化率成反比,如果系统中必须有50%的代码串行执行,那么系统的最大加速比为2。

假设有一程序分为以下步骤执行,每个执行步骤花费100个时间单位。其中,只有步骤2和步骤5可以进行并行,步骤1、3、4必须串行,如图1.2所示。在全串行的情况下,系统合计耗时500个时间单位。

图1.2串行工作流程

若将步骤2和步骤5并行化,假设在双核处理上,则有如图1.3所示的处理流程。在这种情况下,步骤2和步骤5的耗时将为50个是单位。故系统整体耗时为400个时间单位。根据加速比的定义有:

加速比=优化前系统耗时/优化后系统耗时=500/400=1.25

或者前文中给出的加速比公式。由于5个步骤中,3个步骤必须串行,因此其串行化比重为3/5=0.6,即F=0.6,且双核处理器的处理器个数N为2。代入公式得:

加速比=1/(0.6+(1-0.6)/2)=1.25

图1.3双核处理上的并行化

在极端情况下,假设并行处理器个数为无穷大,则有如图1.4所示的处理过程。步骤2和步骤5的处理时间趋于0。即使这样,系统整体耗时依然大于300个时间单位。即加速比的极限为500/300=1.67。

图1.4极端情况下的并行化

使用加速比计算公式,N趋于无穷大,有Speedup=1/F,且F=0.6,故有Speedup=1.67。

由此可见,为了提高系统的速度,仅增加CPU处理器的数量并不一定能起到有效的作用,需要从根本上修改程序的串行行为,提高系统内可并行化的模块比重,在此基础上,合理增加并行处理器数量,才能以最小的投入,得到最大的加速比。

注意:根据Amdahl定律,使用多核CPU对系统进行优化,优化的效果取决于CPU的数量以及系统中的串行化程序的比重。CPU数量越多,串行化比重越低,则优化效果越好。仅提高CPU数量而不降低程序的串行化比重,也无法提高系统性能。

1.2性能调优的层次

为了提升系统性能,开发人员可以从系统的各个角度和层次对系统进行优化。除了最常见的代码优化外,在软件架构上、JVM虚拟机层、数据库以及操作系统层面都可以通过各种手段进行调优,从而在整体上提升系统的性能。

图书网:Java程序性能优化 让你的Java程序更快 更稳定pdf

继续阅读

→→→→→→→→→→→→→→→→→→→→查找获取

程序设计

重构 改善既有代码的设计(中文版)pdf

《重构:改善既有代码的设计》(中文版)所提的这些重构准则将帮助你一次一小步地修改你的代码,这就减少了过程中的风险。很快你就会把这些重构准则和其名称加入自己的开发词典中,并且朗朗上口...
程序设计

数据结构 C语言版 第2版pdf

适读人群 :普通高校电子信息大类本科生学习、考研,同时也适合零售和培训。 采用“案例驱动”的编写模式。书中结合实际应用,将各章按照“案例引入——数据结构及其操作——案例分析与实现”...
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: