java性能优化权威指南

java性能优化权威指南_第1张图片
image.png

常用的监控指令
监控线程上下文切换 pidstat -w -I -p 9391 5 解释: pidstat -w每5秒监控进程id为9391的java应用

下面估计上下文切换锁浪费的时钟周期。处理器为3.0GHZ 双核
pidstat -w 显示系统每秒大约发生3500个上下文切换。每个虚拟处理器的上下文切换为3500/2-1750,耗费的时钟周期为1750*8000=140000000,3ghz cpu每秒的时钟周期数为3000000000.因此上下文切换浪费的时钟周期为
14000000/3000000000=4.7%.再次应用一般性准则(即让步时钟周期占用3-5%或者更多的时钟周期),说明java引用正面锁竞争。P25

2.4.8监控抢占式上下文切换
主动切换和 被动切换

2.4.9 监控线程迁移
待运行线程在处理器之间的迁移也会导致性能下降。大多数操作系统的CPU调度程序会将代运行线程分配给上次运行它的虚拟处理器。迁移线程会造成性能影响是因为新的虚拟处理器缓存中没有代运行线程所需的数据或状态信息。减少迁移的策略是创建处理器组并将java应用分配给这些处理器组。一般性的准则是,如果横跨多个核或虚拟处理器的java引用每秒迁移超过500次,将java应用绑定在处理器组上就有好处。

2.5 网络I/O使用率
2.5.2 Linux 监控网络I/O使用率

image.png

2.6磁盘I/O利用率
iostat -xm 5

第3章
JVM 概览
hotspot VM运行时:命令行选项解析、VM生命周期的管理、类加载、字节码解释、异常处理、同步、线程管理、java本地接口、VM知名错误处理和c++堆管理
启动步骤:p43

3.2.8 同步
HotSpot VM用monitor对象来保障线程运行代码之间的互斥。java的monitor对象可以锁定或者解锁,但任何时刻只能有一个线程拥有该monitor对象,只有获得Monitor对象的所有权后,线程才可以进入它锁保护的临界区,Java中临界区由同步快(Synchronzed Block)表示

VM吸收了非竞争和竞争性同步操作的先进技术,jdk1.5引入偏向锁(命令行-XX:+UseBiasedLocking)、最好情况下成本甚至为零。既然大多数对象在其生命期中最多只会被一个线程锁住,那就可以开启-XX:+UseBiasedLocking允许线程自身使用偏向锁。一旦开启偏向锁,该线程不需要借助昂贵的原子指令就可以对该对象进行锁定和解锁了。
大多数HotSpot VM 同步操作使用称为fast-path代码,hotspot VM 有两个JIT编译器和一个解释器,它们都可以称为fast-path代码,C1-----clientJIT编译器和C2-------- -ServerJIT编译器。 C1和C2在同步点时都可以直接生成fast-path代码,没有竞争时,同步操作通常全部在fast-path代码中完成。,然而需要阻塞或者唤醒线程(分别是monitor-enter 或者monitor-exit状态),fast-path代码将第阿勇slow-path代码。slow-path代码由c++实现,而-fast-path代码则是JIT编译器产生机器代码。

HotSpot vm内部表示java对象的第一个字(word),包括了java对象的同步状态编码,通常称为标记字(mark word)为了节约空间,标记字会根据不同的状态,服用存储空间,包含其他的同步元数据。

3.2.12 VM致命错误处理

OutOfMemoryError

HotSpot VM 生成的错误信息中包含了栈的最终信息,此外还引入了-XX:OnOutOfMemoryError= 所以当抛出第一个OutOfMemoryError时,可以执行一条命令,另一个值得提及的有用的特性是,当OutOfMemoryError出现时候可以生成堆的转存信息。指定-XX:HeapDumpOnOutMemory可以开启的这个特性。另外一个HotSpot VM 命令行选项 -XX:HeapDump- Path=可让用户指定堆转储的存放路径。

退出发送 SIGOUIT信号给java进程id也可以得到同样的效果。基于线程的栈追踪信息,可以分析死锁根源,自带的JConsole工具添加了一项功能,可以联系到一个挂起的java进程并分析死锁的根源。多数情况下,死锁是由于获取锁的顺序错误锁导致的

java性能优化权威指南_第2张图片
minor GC

重要的HotSpot VM 选项

-client
-server
-d64 加载64位hotspot VM而不是默认的32位hotspot VM
当堆内存需要32G以上的时候采用该选项,-Xmx -Xms 小于32G时,该选项要与-XX+UseCompressedOops联合使用 jdk6 后默认开启

java引用的长度从32位增加到64位,这给64位JVM带来了性能损失。长度的增加使得缓存行中可容纳的oops(普通对象指针)变少----因为64地址长度变大 直接导致实际数据存储量的下降,CPU高速缓存的效率也降低。

-xms[g|m|k] 默认堆
-xmx[g|m|k] 最大堆
-XX:NewSize=[g|m|k]最小新生代
-XX:MaxNewSize=[g|m|k]最大
-Xmn[g|m|k]同时设置新生代的初始,最小和最大尺寸
-XX:NewRatio=新生代和老年代的尺寸比例 n默认为3 比例为1:3
-XX:PermSize=[g|m|k]
-XX:MaxPermSize=[g|m|k]
-XX:SurvivorRatio=n 单块Survivor区和Eden区大小比例
。。。P416

你可能感兴趣的:(java性能优化权威指南)