最近线上发生Java进程疯狂写磁盘的杯具,虽然没有造成大碍.由此可以想到如果在出现问题的时候能够快速定位到相应的线程,然后通过其它工具确定该线程堆栈信息,就可以很大程度上解决问题.
每个进程,在/proc目录下都对应一个子目录(以该进程id命名),关于该目录每个伪文件的内容,这里不一一细说。而进程所有的线程,都在task子目录下,目录结构是:/proc/[pid]/task/[tid]。其中/proc/[pid]和/proc/[pid]/task/[tid]这两个目录下的文件名和格式基本上一致,主要是由于Linux不存在NT式的原生线程支持,线程也是以LWP(light weight processes)的方法运行。而这里只关心其中一个即io这个文件,该文件的内容实际上就是进程的实时io信息,例如:
根据
linux
内核文档(链接见末尾)说明,各个分量含义如下:
rchar
:读计数器。所有传送给
read
系统调用的
count
的和值,显然,像输出到控制台
(printf)
这种操作,也会被计入该计数器。注意
read
并不一定每次都会读
count
指定的那么多数据。
[
read
系统调用原型:
ssize_t read(int fd, void *buf, size_t count);
]
wchar
:类似于
rchar
,只不过是写操作
syscr
:
read
系统调用被调用的次数;
syscw
:
write
系统调用被调用的次数;
read_bytes
:实际发生块设备读的字节数;
write_bytes
:实际发生块设备写的字节数;
对于我们而言,最后两个分量才是最有价值的,最能体现进程读写磁盘的情况。
根据个人的研究,很多工具如
dstat
也是利用这个原理的。
一旦获取了线程
id
,就可以很方便的再使用
jstack
来分析该线程的调用堆栈,看看它究竟在干啥了。
最后,我也写了一个
python
脚本,可以输出某个进程前
10
个读写最大的线程
id
。
http://code.google.com/p/sdkfz000/source/browse/trunk/tio/tio.py
本文转自 kevx 51CTO博客,原文链接:http://blog.51cto.com/spinlock/1140104,如需转载请自行联系原作者