310 likes | 526 Views
性能调优. 摘要. Linux 系统资源监控 JVM 内存管理 Profiler 工具介绍 程序优化经验. Linux 内存管理. 查看内存分配 Free Buffer/Cache 系统文件缓存,可以快速释放给应用程序 A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use.
E N D
摘要 • Linux系统资源监控 • JVM内存管理 • Profiler工具介绍 • 程序优化经验
Linux内存管理 • 查看内存分配 Free • Buffer/Cache • 系统文件缓存,可以快速释放给应用程序 • A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use. • total used free shared buffers cached • Mem: 33013644 28049128 4964516 0 1819956 20741200 • -/+ buffers/cache: 5487972 27525672 • Swap: 2096440 780 2095660
Linux CPU内存监控 • Top
Linux磁盘IO监控 • Iostat • rpmms@app-30:~/index/lucene$ iostat -x • Linux 2.6.26-2-amd64 (app-30.photo.163.org) 2011年11月04日 _x86_64_ • avg-cpu: %user %nice %system %iowait %steal %idle • 0.65 0.00 0.37 0.11 0.00 98.87 • Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-szavgqu-szawaitsvctm%util • sda 0.01 9.80 0.74 3.84 18.98 150.37 36.98 0.14 29.67 1.66 0.76 • sda1 0.00 0.62 0.00 0.28 0.03 7.20 25.51 0.00 9.74 2.05 0.06 • sda2 0.00 0.00 0.00 0.00 0.00 0.00 2.00 0.00 40.00 40.00 0.00 rkB/s: 每秒读K字节数。 wkB/s: 每秒写K字节数。 avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区)。 avgqu-sz: 平均I/O队列长度。 await: 平均每次设备I/O操作的等待时间 (毫秒)。 svctm: 平均每次设备I/O操作的服务时间 (毫秒)。 %util: 有百分之多少的时间用于 I/O 操作 rrqm/s: 每秒进行 merge 的读操作数目。即 delta(rmerge)/s wrqm/s: 每秒进行 merge 的写操作数目。即 delta(wmerge)/s r/s: 每秒完成的读 I/O 设备次数。即 delta(rio)/s w/s: 每秒完成的写 I/O 设备次数。即 delta(wio)/s rsec/s: 每秒读扇区数。即 delta(rsect)/s wsec/s: 每秒写扇区数。即 delta(wsect)/s
Linux磁盘IO监控 • Iotop
文件句柄 • 文件句柄上限 通过ulimit命令查看和修改 • lsof 查看占用的文件句柄,常用参数: • -p <PID>,仅显示指定进程占用的 • -i,仅显示网络文件句柄,可用于过滤连接 • -n,取消域名解析,加快处理 • -s,显示文件大小,对于网络连接可用于过滤连接状态
Linux网络监控 • 连接数上限 • 端口数 • 文件句柄数,每个连接占用一个文件句柄 • Netstat 查看网络连接状态与数量 常用参数: • -p 显示连接所属pid,配合grep可以看出特定进程、端口的连接状况 • -n 显示ip地址,不尝试解析域名 • -l 只显示监听端口 • -a 同时显示网络连接与监听端口
Linux网络监控 • Iftop按连接查看网络带宽占用 • nethogs按进程统计占用总带宽与流量
Linux网络监控 • Iptraf 简单图形化界面,能按网卡、端口、包大小等,查看如流量等统计信息 • Netperf 客户端与服务器,能直接测试两台服务器之间的吞吐量 服务器端运行:netserver 客户端运行:netperf -H 172.16.38.36 -l 10
Linux系统监控工具 • Vmstat • fs@fs-50:~/tomcat-cloud-rpc$ vmstat -SM • procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- • r b swpd free buff cache si so bi bo in cs us sy id wa • 0 0 819 1283 323 10011 0 0 15 47 0 0 5 1 95 0 • Swap • si: 虚拟内存由磁盘调入内存 • so: 虚拟内存由内存调入磁盘 • Io • bi: 从块设备读入的数据总量(读磁盘) • bo: 写入到块设备的数据总理(写磁盘) • Procs • r: 运行的和等待(CPU时间片)运行的进程数,这个值也可以判断是否需要增加CPU(长期大于1) • b: 处于不可中断状态的进程数,常见的情况是由IO引起 • Memory • swpd: 切换到交换内存上的内存 • System • in: 每秒产生的中断次数 • cs: 每秒产生的上下文切换次数 • Cpu • us: 用户进程消耗的CPU时间百分比 • sy: 内核进程消耗的CPU时间百分比 • id: CPU处在空闲状态时间百分比 • wa: IO等待消耗的CPU时间百分比
垃圾回收概述 • 目的 找出没用的对象进行释放 • 如何找出“已死”对象? • 引用计数算法 • 根搜索算法 • 如何回收空间 • 标记-清除 -> 空间碎片多 • 复制 -> 空间浪费多 • 标记-整理 -> 效率低 • 分代收集 -> 因地制宜
JVM内存分代管理机制 • Stack • Heap • Eden • Survivor * 2 • Tenured • Perm • Direct
JVM内存分配策略 • 局部变量表(基本数据类型,对象引用指针)、动态链接、方法出口等存在Stack • 新对象一般在eden+survivor中分配(新生代) • 新生代满了进行Minor GC,存活对象拷贝到另一个survivor,原survivor+eden清空 • 如果survivor不足或对象满足晋升条件,则进入老年代,移动到Tenured区 • Tenured不足触发Full GC,Full GC代价高 • Perm用于存放类、常量信息等 • Direct用于native方法空间分配,如NIO
JVM GC监控方法 • 打印GC日志 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log • Jstat工具 实时监控jvm个内存池的空间使用情况,以及gc次数和占用时间 • VisualVM
JVM GC算法 • Serial - 新/老生代,单线程,最基本的GC策略 • ParNew - 新生代,Serial多线程版本,利用多核缩短全局停顿时间 • Parallel Scavenge - 新生代,多线程,关注总体吞吐量 • Parallel Old - 老生代,Parallel Scavenge老年代版本 • CMS - 老生代,多线程,全局停顿时间短,”标记-清除“算法,碎片多,需要Serial作为后备FullGC • G1(Garbage First,JDK 7)
Parallel Scavenge / Old • 目标 • 达到可控的吞吐量 • 核心思想 • GC策略根据设定的吞吐率、最大停顿时间、当前jvm负载等,决定gc运行时机,而不完全在空间满了的情况下执行GC。 • 如果需要缩短停顿时间,会缩小新生代或让gc运行更频繁
Concurrent Mark Sweep(CMS) • 目标 • 实现最短的回收停顿时间 • 核心思想 把回收分成多个阶段: • 初始标记,停顿,仅标记根节点 • 并发标记,从根节点出发标记所有活对象 • 重新标记,停顿,修正并发标记阶段的数据变动 • 并发清除,清除所有垃圾对象 • 缺点 • GC线程与用户线程并发,影响效率 • 无法处理浮动垃圾——并发清除阶段生成的垃圾 • 空间碎片多 • 在由于空间碎片或没法及时清理出可用空间时会使用Serial Old进行FullGC
Gargage First (G1) • 目标 • 高吞吐率+低停顿时间 • 核心思想 • 把整个堆划分位多个独立区域,每个区域都有新/老生代的概念,但没有明确的划分 • 跟踪每个区域的垃圾堆积程度,后台维护优先列表,优先回收垃圾最多的区域,保证在有限时间内获得最高的收集效率 • 优点 • 可以明确指定毫秒时间片内GC停顿不超过指定值,几乎是实时Java的垃圾收集器 • 回收吞吐率高 • JDK 7中实验性回收策略
GC效率对比 • 新生代垃圾为主 • ParNew • Parallel Scavenge • 老生代垃圾为主 • Serial 0.9s • Parallel Old 0.7s • CMS 0.003s
常用Profiler工具 • 常用Profiler产品 • 收费 • JProfiler • Yourkit Java Profiler • 免费 • TPTP(Test and Performance Tools Platform) • 基于java代理机制 使用简单,功能强大,但对性能影响较大。 • 适用场景 • 查看内存耗在哪里 • 查看是否有内存泄露 • 线程执行状态,锁等待、io block
基于AspectJ进行profile(AJProfiler) • AspectJ简介 基于编译时代码插入的Java AOP支持,对性能影响小 • Profile原理 基于AOP,在需要监控的方法执行前后记录系统时间,计算方法执行时间进行各种统计。 • 项目地址 http://qa.hz.netease.com/projects/netease498591/news • 主要功能 • 请求时间吞吐率监控 • 函数调用时间Profile监控
AJProfiler使用方法 • 使用方法 • 加入maven编译依赖 • 添加需要代码插入的依赖包列表 • 添加指定监控函数切面文件 • 重新编译项目 • 启用jmx监控 • 具体参考使用说明文档 http://qa.hz.netease.com/attachments/download/35193?nav=211
程序优化经验 • 重点从算法、逻辑上优化 • 避免保存重复的String对象 • 小心使用String.subString()与String.intern() • 不要用Log4j输出文件名、行号 • Log4j通过打印线程堆栈实现,生成大量String • 少用finalizer • 避免过多使用java序列化 • Memcached客户端选择,gwhalin和spy对比 • 优先考虑适用返回值而不是异常表示错误