Linux 性能监控
uptime
系统时间
运行时间:例子中为7分钟
连接数: 每一个终端算一个进程
1,5,15分钟内的系统平均负载:运行队列中的平均进程数
Top
- 格式:top -参数
- 作用:Linux的系统“任务管理器”
- 显示信息解释
- 第一行(与uptime相同):系统时间 运行时间 登陆的终端数
Load average(系统负载):1分钟平均值 5分钟平均值 15分钟平均值 注意:三个值越小,系统负载越低
- 第二行:进程总数 运行进程数 睡眠的进程数 停止的进程数 将死的进程数
- 第三行:CPU状态
- 第四行:内存状态 (总数,剩余,已占用等)
- 第五行:swap状态(总数,剩余,已占用等)
通过TOP命令可以详细看出当前系统的CPU、内存、负载以及各进程状态(PID、进程占用CPU、内存、用户)等。从上面的结果看出该系统上安装了MySQL、java,可以看到他们各自的进程ID,假如这时Java进程占用较高的CPU和内存,那么你就要留心了,如果程序中没有计算量特别大、占用内存特别多的代码,可能你的java程序出现了未知的问题,可以根据进程ID做进一步的跟踪。除了通过TOP命令找到进程信息以外,还可以通过jdk自带的工具JPS直接找到java程序的进程号。
jps
可以看到jps命令直接罗列出了当前系统中存在的java进程,这里第一个是jps命令自己的java进程,而另外一个是我启动的nosql监控工具进程。通过这种方法查询到java程序的进程ID后,可以进一步通过:
top -p 3618 // 这里的3618就是上面查询到的java程序的进程ID
通过此方法可以准确的查看指定java进程的CPU/内存使用情况。
jstat
监视虚拟机各种运行状态信息的命令行工具。用于输出java程序内存使用情况,包括新生代、老年代、元数据区容量、垃圾回收情况。
上述命令输出进程ID为3618的内存使用情况(每2000毫秒输出一次,一共输出20次)
- S0:幸存1区当前使用比例
- S1:幸存2区当前使用比例
- E:伊甸园区使用比例
- O:老年代使用比例
- M:元数据区使用比例
- CCS:压缩使用比例
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
jinfo
查看和修改虚拟机的各项参数
-
jinfo –sysprops 可以查看由System.getProperties()取得的参数
-
jinfo –flag 未被显式指定的参数的系统默认值
-
jinfo –flags(注意s)显示虚拟机的参数
-
jinfo –flag +[参数] 可以增加参数,但是仅限于由java -XX:+PrintFlagsFinal –version查询出来且为manageable的参数
-
jinfo –flag -[参数] 可以去除参数Thread.getAllStackTraces();
jmap
用于生成堆转储快照(一般称为heapdump或dump文件)。jmap的作用并不仅仅是为了获取dump文件,它还可以查询finalize执行队列、Java堆和永久代的详细信息,如空间使用率、当前用的是哪种收集器等。和jinfo命令一样,jmap有不少功能在Windows平台下都是受限的,除了生成dump文件的-dump选项和用于查看每个类的实例、空间占用统计的-histo选项在所有操作系统都提供之外,其余选项都只能在Linux/Solaris下使用。
jmap -dump:live,format=b,file=heap.bin <pid>
Sun JDK提供jhat(JVM Heap Analysis Tool)命令与jmap搭配使用,来分析jmap生成的堆转储快照。
jstack
(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。
在代码中可以用java.lang.Thread类的getAllStackTraces()方法用于获取虚拟机中所有线程的StackTraceElement对象。使用这个方法可以通过简单的几行代码就完成jstack的大部分功能,在实际项目中不妨调用这个方法做个管理员页面,可以随时使用浏览器来查看线程堆栈。
还有jdk本身自带的可视化工具Jconsole、VisualVM。
浅堆和深堆
浅堆 :(Shallow Heap)是指一个对象所消耗的内存。例如,在32位系统中,一个对象引用会占据4个字节,一个int类型会占据4个字节,long型变量会占据8个字节,每个对象头需要占用8个字节。
深堆 :这个对象被GC回收后,可以真实释放的内存大小,也就是只能通过对象被直接或间接访问到的所有对象的集合。通俗地说,就是指仅被对象所持有的对象的集合。深堆是指对象的保留集中所有的对象的浅堆大小之和。
举例:对象A引用了C和D,对象B引用了C和E。那么对象A的浅堆大小只是A本身,不含C和D,而A的实际大小为A、C、D三者之和。而A的深堆大小为A与D之和,由于对象C还可以通过对象B访问到,因此不在对象A的深堆范围内。