工具是为测试目标服务的,关键是分析的方法和思路,在项目中积累经验,poptest是业内唯一一家培养测试开发工程师的机构,在培训中遴选了大量的案例,通过案例来帮助学员提高自动化测试经验,性能测试经验,
问题:
程序运行的服务器cpu使用率很高,96%左右的使用率
分析:
1,程序属于CPU密集型,(可以看我前面的文章)。
2,程序代码问题,死循环。
定位:
1,通过top命令,PID显示8792的Java进程占用CPU高达98%。
2,定位线程或代码,显示线程列表,并按照CPU占用高的线程排序:
[root@localhost logs]# ps -mp 8792-o THREAD,tid,time | sort -rn
显示结果如下:
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
root 10.5 19 - - - - 6665 00:15:46
root 10.1 19 - - - - 6666 00:15:54
找到了耗时最高的线程6665,占用CPU时间有??分钟了!
将需要的线程ID转换为16进制格式:
[root@localhost logs]# printf "%x\n" 7777
ka
3.打印线程堆栈信息:
[root@localhost logs]# jstack 8792|grep ka -A 30
为什么是这么个分析过程呢,我们反向来解析,研究代码层的情况,可能多你理解更加有效。如果大家对课程感兴趣可以到poptest.cn咨询,欢迎大家来咨询课程
一.假想资源问题:
新接一个项目,只有老大和小弟俩人来干。
但是俩人都需要休息,只有一个休息的房间(共享的资源)。
老板和小弟轮流休息,老大一周休息
5
天,小弟一周休息
2
天,
如此干了
100
周,项目结束。(资源共享)
处理这个两个线程共享休息室问题
package
javaAdvanced;
/**
* @auther cuiH
* Date: 13-10-23
*/
public
class
TraditionalThreadCommunication {
public
static
void
main(String[] args) {
final
RestRoom restRoom =
new
RestRoom();
//进行调用
new
Thread(
new
Runnable() {
@Override
public
void
run() {
//子线程进行50个10循环
for
(
int
i =
1
; i <=
100
; i++) {
/**
* 字节码进行加锁TraditionalThreadCommunication.class 最简单的方式
* 可以使用,但是不适合比较大的程序
* 采用面向对象的方式,将相关联的方法处理为一个对象
* filter拦截就是一种同步机制
*/
// synchronized (TraditionalThreadCommunication.class) {
// for (int j = 1; j <= 10; j++) {
// System.out.println("sub thread sequence " + i + " loop of " + j);
// }
// }
try
{
restRoom.coder(i);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
}
).start();
//main线程进行50 个循环
for
(
int
i =
1
; i <=
100
; i++) {
try
{
restRoom.boss(i);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
}
class
RestRoom {
private
boolean
bShouldBoss =
true
;
//锁,相当于信号量机制的信号量
public
synchronized
void
coder(
int
i)
throws
InterruptedException {
if
(!bShouldBoss) {
this
.wait();
//等待
}
for
(
int
j =
1
; j <=
2
; j++) {
System.out.println(
"小弟休息第 "
+ j +
" 天,第"
+ i +
" 次休息"
);
}
bShouldBoss =
false
;
this
.notify();
//唤醒进程
}
public
synchronized
void
boss(
int
i)
throws
InterruptedException {
if
(bShouldBoss) {
this
.wait();
//等待
}
for
(
int
j =
1
; j <=
5
; j++) {
System.out.println(
"老大休息第 "
+ j +
" 天,第"
+ i +
" 次休息"
);
}
bShouldBoss =
true
;
this
.notify();
}
}
小弟休息第
1
天,第
1
次休息
小弟休息第
2
天,第
1
次休息
老大休息第
1
天,第
1
次休息
老大休息第
2
天,第
1
次休息
老大休息第
3
天,第
1
次休息
老大休息第
4
天,第
1
次休息
老大休息第
5
天,第
1
次休息
小弟休息第
1
天,第
2
次休息
小弟休息第
2
天,第
2
次休息
老大休息第
1
天,第
2
次休息
老大休息第
2
天,第
2
次休息
老大休息第
3
天,第
2
次休息
老大休息第
4
天,第
2
次休息
老大休息第
5
天,第
2
次休息
。。。
。。。
小弟休息第
1
天,第
100
次休息
小弟休息第
2
天,第
100
次休息
老大休息第
1
天,第
100
次休息
老大休息第
2
天,第
100
次休息
老大休息第
3
天,第
100
次休息
老大休息第
4
天,第
100
次休息
老大休息第
5
天,第
100
次休息