44:beer : [ show-busy-java-threads.sh] ( ../show-busy-java-threads.sh )
55----------------------
66
7- 在排查 ` Java ` 的` CPU ` 性能问题时 (` top us ` 值过高),要找出 ` Java ` 进程中消耗` CPU ` 多的线程,并查看它的线程栈,从而找出导致性能问题的方法调用 。
7+ 用于快速排查 ` Java ` 的` CPU ` 性能问题 (` top us ` 值过高),自动查出运行的 ` Java ` 进程中消耗` CPU ` 多的线程,并打印出其线程栈,从而确定导致性能问题的方法调用 。
88
9- PS: 如何操作可以参见[ @bluedavy ] ( http://weibo.com/bluedavy ) 的《分布式Java应用》的【5.1.1 cpu消耗分析】一节,说得很详细:
9+ PS, 如何操作可以参见[ @bluedavy ] ( http://weibo.com/bluedavy ) 的《分布式Java应用》的【5.1.1 cpu消耗分析】一节,说得很详细:
1010
11- 1 . ` top ` 命令找出有问题` Java ` 进程及其线程号 :
11+ 1 . ` top ` 命令找出有问题` Java ` 进程及线程 ` id ` :
1212 1 . 开启线程显示模式
1313 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 . 查看对应的线程栈
1819
19- 查问题时,会要多次这样操作,** 太繁琐** 。
20-
21- 这个脚本的功能是,打印出在运行的` Java ` 进程中,消耗` CPU ` 最多的线程栈(缺省是5个线程)。
20+ 查问题时,会要多次这样操作以确定问题,上面过程** 太繁琐太慢了** 。
2221
2322### 用法
2423
2524``` bash
25+ show-busy-java-threads.sh
26+ # 从 所有的 Java进程中找出最消耗CPU的线程(缺省5个),打印出其线程栈。
27+
2628show-busy-java-threads.sh -c < 要显示的线程栈数>
27- # 上面会从所有的Java进程中找出最消耗CPU的线程,这样用更方便。
2829
2930show-busy-java-threads.sh -c < 要显示的线程栈数> -p < 指定的Java Process>
3031
@@ -39,7 +40,7 @@ sudo show-busy-java-threads.sh
3940### 示例
4041
4142``` bash
42- $ show-busy-java-threads.sh
43+ $ show-busy-java-threads.sh
4344[1] Busy(57.0%) thread(23355/0x5b3b) stack of java process(23269) under user(admin):
4445" pool-1-thread-1" prio=10 tid=0x000000005b5c5000 nid=0x5b3b runnable [0x000000004062c000]
4546 java.lang.Thread.State: RUNNABLE
@@ -90,11 +91,9 @@ $ show-busy-java-threads.sh
9091:beer : [ show-duplicate-java-classes] ( ../show-duplicate-java-classes )
9192----------------------
9293
93- 找出` java ` 库(即 ` jar ` 文件)或` class ` 目录中的重复类 。
94+ 找出` Java Lib ` ( ` Java ` 库,即 ` Jar ` 文件)或` Class ` 目录(类目录)中的重复类 。
9495
95- ` java ` 开发的一个麻烦的问题是` jar ` 冲突(即多个版本的` jar ` ),或者说重复类。会出` NoSuchMethod ` 等的问题,还不见得当时出问题。
96-
97- 找出有重复类的` jar ` ,可以防患未然。
96+ ` Java ` 开发的一个麻烦的问题是` Jar ` 冲突(即多个版本的` Jar ` ),或者说重复类。会出` NoSuchMethod ` 等的问题,还不见得当时出问题。找出有重复类的` Jar ` ,可以防患未然。
9897
9998### 用法
10099
@@ -112,10 +111,72 @@ show-duplicate-java-classes path/to/lib_dir1 /path/to/lib_dir2
112111# 查找多个指定Class目录下的重复类。 Class目录 通过 -c 选项指定
113112show-duplicate-java-classes -c path/to/class_dir1 -c /path/to/class_dir2
114113
115- # 查找指定Class目录和指定目录下所有Jar中的重复类的jar
114+ # 查找指定Class目录和指定目录下所有Jar中的重复类的Jar
116115show-duplicate-java-classes path/to/lib_dir1 /path/to/lib_dir2 -c path/to/class_dir1 -c path/to/class_dir2
117116```
118117
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+
119180### 示例
120181
121182``` bash
0 commit comments