4
4
:beer : [ show-busy-java-threads.sh] ( ../show-busy-java-threads.sh )
5
5
----------------------
6
6
7
- 在排查 ` Java ` 的` CPU ` 性能问题时 (` top us ` 值过高),要找出 ` Java ` 进程中消耗` CPU ` 多的线程,并查看它的线程栈,从而找出导致性能问题的方法调用 。
7
+ 用于快速排查 ` Java ` 的` CPU ` 性能问题 (` top us ` 值过高),自动查出运行的 ` Java ` 进程中消耗` CPU ` 多的线程,并打印出其线程栈,从而确定导致性能问题的方法调用 。
8
8
9
- PS: 如何操作可以参见[ @bluedavy ] ( http://weibo.com/bluedavy ) 的《分布式Java应用》的【5.1.1 cpu消耗分析】一节,说得很详细:
9
+ PS, 如何操作可以参见[ @bluedavy ] ( http://weibo.com/bluedavy ) 的《分布式Java应用》的【5.1.1 cpu消耗分析】一节,说得很详细:
10
10
11
- 1 . ` top ` 命令找出有问题` Java ` 进程及其线程号 :
11
+ 1 . ` top ` 命令找出有问题` Java ` 进程及线程 ` id ` :
12
12
1 . 开启线程显示模式
13
13
1 . 按` CPU ` 使用率排序
14
- 1 . 记下` Java ` 进程号及其` CPU ` 高的线程号
15
- 1 . 手动转成十六进制(可以用` printf %x 1234 ` )。
16
- 1 . ` jstack ` 有问题的` Java ` 进程。
17
- 1 . ` grep ` 十六进制的线程` id ` ,找到线程栈。
14
+ 1 . 记下` Java ` 进程` id ` 及其` CPU ` 高的线程` id `
15
+ 1 . 用进程` id ` 作为参数,` jstack ` 有问题的` Java ` 进程
16
+ 1 . 手动转换线程` id ` 成十六进制(可以用` printf %x 1234 ` )
17
+ 1 . 查找十六进制的线程` id ` (可以用` grep ` )
18
+ 1 . 查看对应的线程栈
18
19
19
- 查问题时,会要多次这样操作,** 太繁琐** 。
20
-
21
- 这个脚本的功能是,打印出在运行的` Java ` 进程中,消耗` CPU ` 最多的线程栈(缺省是5个线程)。
20
+ 查问题时,会要多次这样操作以确定问题,上面过程** 太繁琐太慢了** 。
22
21
23
22
### 用法
24
23
25
24
``` bash
25
+ show-busy-java-threads.sh
26
+ # 从 所有的 Java进程中找出最消耗CPU的线程(缺省5个),打印出其线程栈。
27
+
26
28
show-busy-java-threads.sh -c < 要显示的线程栈数>
27
- # 上面会从所有的Java进程中找出最消耗CPU的线程,这样用更方便。
28
29
29
30
show-busy-java-threads.sh -c < 要显示的线程栈数> -p < 指定的Java Process>
30
31
@@ -39,7 +40,7 @@ sudo show-busy-java-threads.sh
39
40
### 示例
40
41
41
42
``` bash
42
- $ show-busy-java-threads.sh
43
+ $ show-busy-java-threads.sh
43
44
[1] Busy(57.0%) thread(23355/0x5b3b) stack of java process(23269) under user(admin):
44
45
" pool-1-thread-1" prio=10 tid=0x000000005b5c5000 nid=0x5b3b runnable [0x000000004062c000]
45
46
java.lang.Thread.State: RUNNABLE
@@ -90,11 +91,9 @@ $ show-busy-java-threads.sh
90
91
:beer : [ show-duplicate-java-classes] ( ../show-duplicate-java-classes )
91
92
----------------------
92
93
93
- 找出` java ` 库(即 ` jar ` 文件)或` class ` 目录中的重复类 。
94
+ 找出` Java Lib ` ( ` Java ` 库,即 ` Jar ` 文件)或` Class ` 目录(类目录)中的重复类 。
94
95
95
- ` java ` 开发的一个麻烦的问题是` jar ` 冲突(即多个版本的` jar ` ),或者说重复类。会出` NoSuchMethod ` 等的问题,还不见得当时出问题。
96
-
97
- 找出有重复类的` jar ` ,可以防患未然。
96
+ ` Java ` 开发的一个麻烦的问题是` Jar ` 冲突(即多个版本的` Jar ` ),或者说重复类。会出` NoSuchMethod ` 等的问题,还不见得当时出问题。找出有重复类的` Jar ` ,可以防患未然。
98
97
99
98
### 用法
100
99
@@ -112,10 +111,72 @@ show-duplicate-java-classes path/to/lib_dir1 /path/to/lib_dir2
112
111
# 查找多个指定Class目录下的重复类。 Class目录 通过 -c 选项指定
113
112
show-duplicate-java-classes -c path/to/class_dir1 -c /path/to/class_dir2
114
113
115
- # 查找指定Class目录和指定目录下所有Jar中的重复类的jar
114
+ # 查找指定Class目录和指定目录下所有Jar中的重复类的Jar
116
115
show-duplicate-java-classes path/to/lib_dir1 /path/to/lib_dir2 -c path/to/class_dir1 -c path/to/class_dir2
117
116
```
118
117
118
+ #### ` JDK ` 开发场景使用说明
119
+
120
+ 以` Maven ` 作为构建工程示意过程。
121
+
122
+ #### 对于一般的工程
123
+
124
+ ``` sh
125
+ # 在项目模块目录下执行,拷贝依赖Jar到目录target/dependency下
126
+ $ mvn dependency:copy-dependencies -DincludeScope=runtime
127
+ ...
128
+ # 检查重复类
129
+ $ show-duplicate-java-classes target/dependency
130
+ ...
131
+ ```
132
+
133
+ #### 对于` Web ` 工程
134
+
135
+ 对于` Web ` 工程,即` war ` ` maven ` 模块,会打包生成` war ` 文件。
136
+
137
+ ``` sh
138
+ # 在war模块目录下执行,生成war文件
139
+ $ mvn install
140
+ ...
141
+ # 解压war文件,war文件中包含了应用的依赖的Jar文件
142
+ $ unzip target/* .war -d target/war
143
+ # 检查重复类
144
+ $ show-duplicate-java-classes -c target/war/WEB-INF/classes target/war/WEB-INF/lib
145
+ ...
146
+ ```
147
+
148
+ #### ` Android ` 开发场景使用说明
149
+
150
+ ` Android ` 开发,有重复类在编译打包时会报` [Dex Loader] Unable to execute dex: Multiple dex files define Lorg/foo/xxx/Yyy ` 。
151
+
152
+ 但只会给出一个重复类名,如果重复类比较多时,上面打包/报错/排查会要进行多次,而` Android ` 的打包比较费时,这个过程比较麻烦,希望可以一次把所有重复类都列出来,一起排查掉。
153
+
154
+ 以` Gradle ` 作为构建工程示意过程。
155
+
156
+ 在` App ` 的` build.gradle ` 中添加拷贝库到目录` build/dependencies ` 下。
157
+
158
+ ``` java
159
+ task copyDependencies(type: Copy ) {
160
+ def dest = new File (buildDir, " dependencies" )
161
+
162
+ // clean dir
163
+ dest. deleteDir()
164
+ dest. mkdirs()
165
+
166
+ // fill dir with dependencies
167
+ from configurations. compile into dest
168
+ }
169
+ ```
170
+
171
+ ``` sh
172
+ # 拷贝依赖
173
+ $ ./gradlew app:copyDependencies
174
+ ...
175
+ # 检查重复类
176
+ $ show-duplicate-java-classes app/build/dependencies
177
+ ...
178
+ ```
179
+
119
180
### 示例
120
181
121
182
``` bash
0 commit comments