java线上应用问题排查方法和工具

linux性能监测点 CPU, Memory, IO, Network

Linux性能监测工具-cpu

基本概念:

  • 上下文切换(Context Switches): 如果可运行的线程数大于CPU的数量,那么OS最终会强行换出正在执行的线程,从而使其他线程能够使用CPU,它会保存当前运行线程的执行上下文,并重建新调入线程的执行上下文。
  • 运行队列(Run Queue): 每个CPU都维护一个线程的运行队列。如果CPU子系统处于高负荷下,那就意味着内核调度将无法及时响应系统请求. 导致结果,可运行状态进程拥塞在运行队列里.当运行队列越来越巨大,进程线程将花费更多的时间获取被执行.
  • Load: 就是指在CPU 队列中有多少数目的线程,以及其中当前有多少进程线程数目被执行的组合. 安全的load一般是cpu的个数
  • CPU利用率(CPU Utilization): CPU 使用的百分比 User Time, System Time, Wait IO, Idle
  • 中断(Interrupts) – Devices tell the kernel that they are done processing。例子, 当一块网卡设备递送网络数据包或者一块硬件提供了一次IO请求.
  • Run Queues - 每个处理器应该运行队列丌超过1-3个线程. 例子, 一个双核处理器应该运行队列丌要超过6个线程。
  • CPU Utiliation - 如果一个CPU 被充分使用,利用率分类之间均衡的比例应该是: 65%-70% User Time, 30%-35% System Time, 0%-5% Idle Time

查看cpu信息
cat /proc/cpuinfo

获取cpu个数
grep ‘processor’ /proc/cpuinfo | wc –l

uptime
显示系统已经运行了多长时间,它依次显示下列信息:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平 均负载。

相关命令
vmstat (virtual memory statistics) :实时的性能监测工具
1. 上下文切换数目高于中断数目,说明kernel中相当数量的时间都开销在上下文切换线程.
2. 大量的上下文切换将导致CPU 利用率分类不均衡.很明显实际上等待io请求的百分比(wa)非常高,以及user time百分比非常低(us).
3. 因为CPU 都阻塞在IO请求上,所以运行队列里也有相当数目的可运行状态线程在等待执行.

Top: 常用参数:H Show all threads by process, 显示各个CPU的运行情况

mpstat(Multiprocessor Statistics) 不但能查看所有CPU的平均状况信息,而且能够查看特定CPU的信息
sar:能够查看历史数据,也可查看实时
sar –q 查看load状况 sar -q 1 3
sar –u 查看cpu使用率 sar -u 1 10
查看历史某一天的,这个很重要可以和以往进行对比sar -u -f /var/log/sa/sa01

Linux性能监测工具-内存

Virtual Memory: 虚拟内存就是采用硬盘对物理内存进行扩展
kswapd: kswapd进程负责确保内存空间总是在被释放中.
pdflush: 负责将内存中的内容和文件系统进行同步操作.即写操作返回的时候数据并没有真正写到磁盘上,而是先写到了系统cache里,随后由pdflush内核线程将系统中的脏页写到磁盘上
ps -ef | grep kswapd
ps -ef | grep pdflush

cat /proc/meminfo 查看内存信息
ps aux
RSS:物理内存
ps -p javaid -o rss
sar –r :内存和交换分区使用率
sar -r 1 10

  • 大量的disk pages(bi)被写入内存,很明显在进程地址空间里,数据缓存(cache)也在不断的增长.
  • 在这个时间点上,空闲内存(free) 始终保持在17MB,即使数据从硬盘读入而在消耗RAM.
  • 很明显可以看到buffer cache(buff) 在逐渐的减少中.
  • 同时kswapd 进程不断的写脏页到swap device(so)时,很明显虚拟内存的利用率是在逐渐的增加中(swpd)

Linux性能监测工具- Disk I/O

I/O子系统是Linux 系统中最慢的部分. 这个主要是归于CPU到物理操作磁盘之间距离(盘片旋转以及寻道). 如果拿读取磁盘和内存的时间作比较就是分钟级到秒级, 这就像7天和7分钟的区别. 因此本质上Linux 内核就是要最低程度的降低I/O数.

检查文件系统的磁盘空间占用情况
df -ha

以指定的目彔下的子目彔为单位,显示每个目彔内所有档案所占用的磁盘空间大小
du –ah -d1

iostat
常用参数 –x -d

sar -b

Linux性能监测工具-network

ifconfig 网络配置信息 
ping用于查看网络上的主机是否在工作TTL是由发送主机设置的, 以防止数据包不断在IP互联网络上永不终止地循环. 转发IP数据包时, 要求路由器至少将TTL减小1.

netstat 用于显示不IP、TCP、UDP和ICMP协议相关的统计数据, 一般用于检验本机各端口的网络连接情况.
常用参数:
-a或–all显示所有连线中的Socket.
-n或–numeric 直接使用IP地址, 而不通过域名服务器
-p或–programs 显示正在使用Socket的程序识别码和程序名称
-t或–tcp 显示TCP传输协议的连线状况
netstat –anpt

sar -n SOCK查看网络连接资源
totsck Total number of used sockets
tcpsck Number of TCP sockets currently in use.

sar -n DEV 查看网络流量

Linux性能监测工具-其他

lsof: 可以列出被进程所打开的文件的信息.
COMMAND: 进程的名称
PID: 进程标识符
USER: 进程所有者
FD: 文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
TYPE: 文件类型,如DIR、REG等
DEVICE: 指定磁盘的名称
SIZE: 文件的大小
NODE: 索引节点(文件在磁盘上的标识)
NAME: 打开文件的确切名称

管道
下面这个命令用来统计与1234 端口相连的机器数
netstat -antp | grep 1234 | wc –l
查看java线程
ps -eLf | grep java | wc -l
find
find work/ -name
grep
ps -eLf | grep java | wc -l
awk
对收藏夹apache日志 进行页面排序和统计
awk -F" {print $2} 2011-11-02-taobao-access_log |awk {print $2} |awk -F? {print $1} | awk -F- {print $1} | sort | uniq -c | sort -n +0 -1-r > 11.txt

JVM基础及性能监测工具

JVM体系结构

JVM 堆结构

  • Young Generation :Eden - where new objects get Instantiated, 2 Survivor Spaces to hold live objects during minor GC
  • Old Generation: Objects that are longer-lived are eventually promoted or tenured, to the old generation
  • Permanent Generation: VM and Java class metadata as well as interned Strings and class static variables
  • One survivor space is always empty, serves as destination for minor collections。
  • At the end of the minor garbage collection: the two survivor spaces swap roles; the eden is entirely empty; only one survivor space is in use; and the occupancy of the old generation has grown slightly.
  • Major collections occur when the tenured space fills up, major collections free up eden and both survivor spaces.

JVM 堆大小设置

-XX:NewSize
-XX:PermSize
-XX:MaxNewSize
-XX:MaxPermSize
-Xmn(NewSize= MaxNewSize)
-Xms
-Xmx
-XX:NewRatio=n-
-XX:SurvivorRatio=n

If the application has a small data set (up to approximately 100MB), then select the serial collector with -XX:+UseSerialGC

If the application will be run on a single processor and thereare no pause time requirements, thenlet the VM select the collector, orselect the serial collector with -XX:+UseSerialGC

If (a) peak application performance is the first priority and (b) there are no pause time requirements or pauses of onesecond or longer are acceptable, then let the VM select the collector, or select the parallel collector with -XX:+UseParallelGC and (optionally) enable parallel compaction with -XX:+UseParallelOldGC.

If response time is more important than overall throughput and garbage collection pauses must be kept shorter than approximately one second, then select the concurrent collector with -verbose:gc -Xloggc:/home/admin/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps

JVM主要参数
Behavioral options change the basic behavior of the VM.
Performance tuning options are knobs which can be used to tune VMperformance.
Debugging options generally enable tracing, printing, or output of VMinformation.

OutOfMemoryError
内存问题的两个主要发生区段:
Java内存--包括heap堆内存和permanent区
本地内存--包括JVM进程内存和java使用的第三方本地代码

Java内存不足
Java堆内存heap不足,无法再分配新对象或内存块
permanent区内存丌足,无法再加载类到内存中

本地内存不足
物理内存不够,无法再得到内存

第三方本地代码有内存泄漏的Bug,例如oracle oci driver本地代码
JVM的JIT或者JVM本身的Bug

Heap Size Starting Point
From the GC log you will get
Approximation of the Live Data Size (LDS) It is the heap occupancy after each full GC
Approximation of max perm gen size It is the perm gen occupancy after each full GC

Initial Heap Configuration
You can now make an informed decision on choosing areasonable heap size
Rule of thumb
Set -Xms and -Xmx to 3x to 4x LDS
Set both -XX:PermSize and -XX:MaxPermSize to around 1.2x to 1.5x the max perm gen size
Set the generation sizes accordingly

Rule of thumb
Young gen should be around 1x to 1.5x LDS
Old gen should be around 2x to 3x LDS
e.g., young gen should be around 1/3-1/4 of the heap

JVM调优建议
You should try to maximize the number of objects reclaimed in the young generation. This is probably the most important piece of advice when sizing a heap and/or tuning the young generation
Your applications memory footprint should not exceed the available physical memory. This is probably the second most important pieceof advice when sizing a heap
Applications with emphasis on performance tendto set -Xms and -Xmx to the same value, when -Xms != -Xmx, heap growth or shrinkingrequires a Full GC
Applications with emphasis on performance almost always set -XX:PermSize and -XX:MaxPermSize to the same value. Growing or shrinking the permanent generation requires a Full GC too
Try to retain as many objects as possible in the survivor spaces so that they can be reclaimed inthe young generation. Less promotion into the old generation, Less frequent old GCs
But also, try not to unnecessarily copy very long lived objects between the survivors, Unnecessary overhead on minor GCs
Not always easy to find the perfect balance

1. Higher tenuring threshold → promotes fewerobjects
 Possibly (but not necessarily) longer young GC times
Increases the number of objects reclaimed in the young genBetter overall efficiency
2. Lower tenuring threshold → promotes more objects
Possibly (but not necessarily) shorter young GC times
More load / pressure on the old gen
More frequent old GCsCould make fragmentation more severe

Java crash
• A crash, or fatal error, causes a process to terminateabnormally。
• Crash后会产生 hs_err_pid开头的文件,(有时候可能来不及)
• 可能的原因:
– Java虚拟机自身的Bug
– 系统的库文件、API或第三方的库文件造成
– 系统资源的短缺

Crash 文件由以下几部分组成:
• A header that provides a brief description of the crash.
• A section with thread information.
– Thread Information
– Signal Information
– Register Context
– Machine Instructions
– Thread Stack
– Further Details
• A section with process information.
– Thread List
– VMState
– Mutexes and Monitors
– Heap Summary
– MemoryMap

几个crash例子
Crash in Native Code
*

java性能监测工具
jinfo prints Java configuration information for a given Javaprocess or core file or a remote debug server.
打印某个参数 -flag

Jps: lists the instrumented HotSpot Java Virtual Machines (JVMs)on the target system

jmap 内存查看工具
常用参数: -heap -histo –permstat -dump:format=b,file=HeapDump.hprof

jstat可以查看gc情况
常用参数:gcutil,gcnew,gcold,
jstat -gcutil 929 1000

jstack :线程查看工具
jstack java进程id
同killall -3 java

top -H –p javaid
转换 printf 0x%xn 30490

Eclipse Memory Analyzer: a fast and feature-rich heap analyzerthat helps you find memory leaks and high memory consumption issues

Java VisualVM: a tool that provides a visual interface for viewing detailedinformation about Java technology-based applications (Java applications)while they are running on a Java Virtual Machine (JVM)

JConsole

日志分析
Filter日志
应用错误日志
Apache日志

web应用服务器诊断问题常用流程
Web应用服务器,主要是load变高。Load高主要是资源不够导致,比如数据库连接池不够。
1 可以通过 top 和 vmstat 查看load状况
2 通过ps -eLf | grep java | wc –l 统计java线程 通过ps -eLf | grep httpd | wc –l 统计 apache线程 这样可以判断是否是机器在超负荷运转. 也可通过日志大小判断.
3 通过filter日志判断系统慢在什么地方.
4 通过debug日志判断cache, 数据库或者依赖的其他系统是否正常.
5 通过dump 线程查看线程都在干什么.
6 通过jstat 查看java gc状况.
7 通过 dump内存 查看java 内存是否存在泄漏.
8 通过sar看看机器历史记录有助问题排查.
9 经验!!

参考

http://java.sun.com/docs/hotspot/index.html
http://java.sun.com/performance/reference/whitepapers/tuning.html
http://java.sun.com/performance/reference/whitepapers/6_performance.html
《深入理解jvm高级特性与最佳实践》
《Java_Performance》
《Linux_Performance_Monitoring 》
《Performance.Tuning.for.Linux.Servers 》
《Troubleshooting Guide for Java SE6 with HotSpot VM 》
《sed and awk, 2nd Edition》

上一篇:Jconsole远程监控tomcat 的JVM内存(linux、windows)


下一篇:java高并发系列-第1天:必须知道的几个概念