Java相关脚本

本人摘自:https://github.com/oldratlee/useful-scripts/blob/master/docs/java.md#beer-show-busy-java-threadssh

 show-busy-java-threads

用于快速排查JavaCPU性能问题(top us值过高),自动查出运行的Java进程中消耗CPU多的线程,并打印出其线程栈,从而确定导致性能问题的方法调用。
目前只支持Linux。原因是MacWindowsps命令不支持列出线程线程,更多信息参见#33,欢迎提供解法。

PS,如何操作可以参见@bluedavy的《分布式Java应用》的【5.1.1 cpu消耗分析】一节,说得很详细:

  1. top命令找出有问题Java进程及线程id

    1. 开启线程显示模式
    2. CPU使用率排序
    3. 记下Java进程id及其CPU高的线程id
  2. 用进程id作为参数,jstack有问题的Java进程
  3. 手动转换线程id成十六进制(可以用printf %x 1234
  4. 查找十六进制的线程id(可以用grep
  5. 查看对应的线程栈

查问题时,会要多次这样操作以确定问题,上面过程太繁琐太慢了。

用法

show-busy-java-threads
# 从所有运行的Java进程中找出最消耗CPU的线程(缺省5个),打印出其线程栈

# 缺省会自动从所有的Java进程中找出最消耗CPU的线程,这样用更方便
# 当然你可以手动指定要分析的Java进程Id,以保证只会显示出那个你关心的Java进程的信息
show-busy-java-threads -p <指定的Java进程Id>

show-busy-java-threads -c <要显示的线程栈数>

show-busy-java-threads <重复执行的间隔秒数> [<重复执行的次数>]
# 多次执行;这2个参数的使用方式类似vmstat命令

show-busy-java-threads -a <输出记录到的文件>
# 记录到文件以方便回溯查看

##############################
# 注意:
##############################
# 如果Java进程的用户 与 执行脚本的当前用户 不同,则jstack不了这个Java进程
# 为了能切换到Java进程的用户,需要加sudo来执行,即可以解决:
sudo show-busy-java-threads

show-busy-java-threads -s <指定jstack命令的全路径>
# 对于sudo方式的运行,JAVA_HOME环境变量不能传递给root,
# 而root用户往往没有配置JAVA_HOME且不方便配置,
# 显式指定jstack命令的路径就反而显得更方便了

# -m选项:执行jstack命令时加上-m选项,显示上Native的栈帧,一般应用排查不需要使用
show-busy-java-threads -m
# -F选项:执行jstack命令时加上 -F 选项(如果直接jstack无响应时,用于强制jstack),一般情况不需要使用
show-busy-java-threads -F
# -l选项:执行jstack命令时加上 -l 选项,显示上更多相关锁的信息,一般情况不需要使用
# 注意:和 -m -F 选项一起使用时,可能会大大增加jstack操作的耗时
show-busy-java-threads -l

# 帮助信息
$ show-busy-java-threads -h
Usage: show-busy-java-threads [OPTION]... [delay [count]]
Find out the highest cpu consumed threads of java, and print the stack of these threads.

Example:
  show-busy-java-threads       # show busy java threads info
  show-busy-java-threads 1     # update every 1 seconds, (stop by eg: CTRL+C)
  show-busy-java-threads 3 10  # update every 3 seconds, update 10 times

Options:
  -p, --pid <java pid>      find out the highest cpu consumed threads from the specifed java process,
                            default from all java process.
  -c, --count <num>         set the thread count to show, default is 5
  -a, --append-file <file>  specify the file to append output as log
  -s, --jstack-path <path>  specify the path of jstack command
  -F, --force               set jstack to force a thread dump
                            use when jstack <pid> does not respond (process is hung)
  -m, --mix-native-frames   set jstack to print both java and native frames (mixed mode)
  -l, --lock-info           set jstack with long listing. Prints additional information about locks
  -h, --help                display this help and exit
  delay                     the delay between updates in seconds
  count                     the number of updates
                            delay/count arguments imitates style of vmstat command

示例

$ show-busy-java-threads
[1] Busy(57.0%) thread(23355/0x5b3b) stack of java process(23269) under user(admin):
"pool-1-thread-1" prio=10 tid=0x000000005b5c5000 nid=0x5b3b runnable [0x000000004062c000]
   java.lang.Thread.State: RUNNABLE
    at java.text.DateFormat.format(DateFormat.java:316)
    at com.xxx.foo.services.common.DateFormatUtil.format(DateFormatUtil.java:41)
    at com.xxx.foo.shared.monitor.schedule.AppMonitorDataAvgScheduler.run(AppMonitorDataAvgScheduler.java:127)
    at com.xxx.foo.services.common.utils.AliTimer$2.run(AliTimer.java:128)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

[2] Busy(26.1%) thread(24018/0x5dd2) stack of java process(23269) under user(admin):
"pool-1-thread-2" prio=10 tid=0x000000005a968800 nid=0x5dd2 runnable [0x00000000420e9000]
   java.lang.Thread.State: RUNNABLE
    at java.util.Arrays.copyOf(Arrays.java:2882)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:572)
    at java.lang.StringBuffer.append(StringBuffer.java:320)
    - locked <0x00000007908d0030> (a java.lang.StringBuffer)
    at java.text.SimpleDateFormat.format(SimpleDateFormat.java:890)
    at java.text.SimpleDateFormat.format(SimpleDateFormat.java:869)
    at java.text.DateFormat.format(DateFormat.java:316)
    at com.xxx.foo.services.common.DateFormatUtil.format(DateFormatUtil.java:41)
    at com.xxx.foo.shared.monitor.schedule.AppMonitorDataAvgScheduler.run(AppMonitorDataAvgScheduler.java:126)
    at com.xxx.foo.services.common.utils.AliTimer$2.run(AliTimer.java:128)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
...

上面的线程栈可以看出,CPU消耗最高的2个线程都在执行java.text.DateFormat.format,业务代码对应的方法是shared.monitor.schedule.AppMonitorDataAvgScheduler.run。可以基本确定:

  • AppMonitorDataAvgScheduler.run调用DateFormat.format次数比较频繁。
  • DateFormat.format比较慢。(这个可以由DateFormat.format的实现确定。)

多执行几次show-busy-java-threads,如果上面情况高概率出现,则可以确定上面的判定。
因为调用越少代码执行越快,则出现在线程栈的概率就越低。
脚本有自动多次执行的功能,指定 重复执行的间隔秒数/重复执行的次数 参数。

分析shared.monitor.schedule.AppMonitorDataAvgScheduler.run实现逻辑和调用方式,以优化实现解决问题。

贡献者

 show-duplicate-java-classes

找出Java LibJava库,即Jar文件)或Class目录(类目录)中的重复类。
全系统支持(Python实现,安装Python即可),如LinuxMacWindows

Java开发的一个麻烦的问题是Jar冲突(即多个版本的Jar),或者说重复类。会出NoSuchMethod等的问题,还不见得当时出问题。找出有重复类的Jar,可以防患未然。

用法

  • 通过脚本参数指定Libs目录,查找目录下Jar文件,收集Jar文件中Class文件以分析重复类。可以指定多个Libs目录。
    注意,只会查找这个目录下Jar文件,不会查找子目录下Jar文件。因为Libs目录一般不会用子目录再放Jar,这样也避免把去查找不期望Jar
  • 通过-c选项指定Class目录,直接收集这个目录下的Class文件以分析重复类。可以指定多个Class目录。
# 查找当前目录下所有Jar中的重复类
show-duplicate-java-classes

# 查找多个指定目录下所有Jar中的重复类
show-duplicate-java-classes path/to/lib_dir1 /path/to/lib_dir2

# 查找多个指定Class目录下的重复类。 Class目录 通过 -c 选项指定
show-duplicate-java-classes -c path/to/class_dir1 -c /path/to/class_dir2

# 查找指定Class目录和指定目录下所有Jar中的重复类的Jar
show-duplicate-java-classes path/to/lib_dir1 /path/to/lib_dir2 -c path/to/class_dir1 -c path/to/class_dir2

# 帮助信息
$ show-duplicate-java-classes -h
Usage: show-duplicate-java-classes [-c class-dir1 [-c class-dir2] ...] [lib-dir1|jar-file1 [lib-dir2|jar-file2] ...]

Options:
  -h, --help            show this help message and exit
  -c CLASS_DIRS, --class-dir=CLASS_DIRS
                        add class dir

JDK开发场景使用说明

Maven作为构建工程示意过程。

对于一般的工程
# 在项目模块目录下执行,拷贝依赖Jar到目录target/dependency下
$ mvn dependency:copy-dependencies -DincludeScope=runtime
...
# 检查重复类
$ show-duplicate-java-classes target/dependency
...
对于Web工程

对于Web工程,即war maven模块,会打包生成war文件。

# 在war模块目录下执行,生成war文件
$ mvn install
...
# 解压war文件,war文件中包含了应用的依赖的Jar文件
$ unzip target/*.war -d target/war
...
# 检查重复类
$ show-duplicate-java-classes -c target/war/WEB-INF/classes target/war/WEB-INF/lib
...

Android开发场景使用说明

Android开发,有重复类在编译打包时会报[Dex Loader] Unable to execute dex: Multiple dex files define Lorg/foo/xxx/Yyy

但只会给出一个重复类名,如果重复类比较多时,上面打包/报错/排查会要进行多次,而Android的打包比较费时,这个过程比较麻烦,希望可以一次把所有重复类都列出来,一起排查掉。

Gradle作为构建工程示意过程。

Appbuild.gradle中添加拷贝库到目录build/dependencies下。

task copyDependencies(type: Copy) {
    def dest = new File(buildDir, "dependencies")

    // clean dir
    dest.deleteDir()
    dest.mkdirs()

    // fill dir with dependencies
    from configurations.compile into dest
}
# 拷贝依赖
$ ./gradlew app:copyDependencies
...
# 检查重复类
$ show-duplicate-java-classes app/build/dependencies
...

示例

$ show-duplicate-java-classes WEB-INF/lib
COOL! No duplicate classes found!

================================================================================
class paths to find:
================================================================================
1  : WEB-INF/lib/sourceforge.spring.modules.context-2.5.6.SEC02.jar
2  : WEB-INF/lib/misc.htmlparser-0.0.0.jar
3  : WEB-INF/lib/normandy.client-1.0.2.jar
...

$ show-duplicate-java-classes -c WEB-INF/classes WEB-INF/lib
Found duplicate classes in below class path:
1  ([email protected]): WEB-INF/lib/sourceforge.spring-2.5.6.SEC02.jar WEB-INF/lib/sourceforge.spring.modules.orm-2.5.6.SEC02.jar
2  ([email protected]): WEB-INF/lib/servlet-api-3.0-alpha-1.jar WEB-INF/lib/jsp-api-2.1-rev-1.jar WEB-INF/lib/jstl-api-1.2-rev-1.jar
3  ([email protected]): WEB-INF/lib/commons-io-2.2.jar WEB-INF/lib/jakarta.commons.io-2.0.jar
4  ([email protected]): WEB-INF/lib/jakarta.commons.logging-1.1.jar WEB-INF/lib/commons-logging-1.1.1.jar WEB-INF/lib/org.slf4j.jcl104-over-slf4j-1.5.6.jar
5  ([email protected]): WEB-INF/lib/sourceforge.spring-2.5.6.SEC02.jar WEB-INF/lib/sourceforge.spring.modules.context-2.5.6.SEC02.jar
...

================================================================================
Duplicate classes detail info:
================================================================================
1  ([email protected]): WEB-INF/lib/sourceforge.spring-2.5.6.SEC02.jar WEB-INF/lib/sourceforge.spring.modules.orm-2.5.6.SEC02.jar
    1   org/springframework/orm/toplink/TopLinkTemplate$13.class
    2   org/springframework/orm/hibernate3/HibernateTemplate$24.class
    3   org/springframework/orm/jpa/vendor/HibernateJpaDialect.class
    4   org/springframework/orm/hibernate3/TypeDefinitionBean.class
    5   org/springframework/orm/hibernate3/SessionHolder.class
    ...
2  ([email protected]): WEB-INF/lib/servlet-api-3.0-alpha-1.jar WEB-INF/lib/jsp-api-2.1-rev-1.jar WEB-INF/lib/jstl-api-1.2-rev-1.jar
    1   javax/servlet/ServletException.class
    2   javax/servlet/ServletContext.class
3  ([email protected]): WEB-INF/lib/commons-io-2.2.jar WEB-INF/lib/jakarta.commons.io-2.0.jar
    1   org/apache/commons/io/input/ProxyReader.class
    2   org/apache/commons/io/output/FileWriterWithEncoding.class
    3   org/apache/commons/io/output/TaggedOutputStream.class
    4   org/apache/commons/io/filefilter/NotFileFilter.class
    5   org/apache/commons/io/filefilter/TrueFileFilter.class
    ...
...

================================================================================
class paths to find:
================================================================================
1  : WEB-INF/lib/sourceforge.spring.modules.context-2.5.6.SEC02.jar
2  : WEB-INF/lib/misc.htmlparser-0.0.0.jar
3  : WEB-INF/lib/normandy.client-1.0.2.jar
4  : WEB-INF/lib/xml.xmlgraphics__batik-css-1.7.jar-1.7.jar
5  : WEB-INF/lib/jakarta.ecs-1.4.2.jar
...

贡献者

tgic提供此脚本。友情贡献者的链接commandlinefu.cn|微博linux命令行精选

 find-in-jars

在当前目录下所有jar文件里,查找类或资源文件。
支持LinuxMacWindowscygwinMSSYS)。

用法

# 在当前目录下所有`jar`文件里,查找类或资源文件。
find-in-jars ‘log4j\.properties‘
find-in-jars ‘log4j\.xml$‘
find-in-jars log4j\\.xml$ # 和上面命令一样,Shell转义的不同写法而已
find-in-jars ‘log4j(\.properties|\.xml)$‘

# -d选项 指定 查找目录(覆盖缺省的当前目录)
find-in-jars ‘log4j\.properties$‘ -d /path/to/find/directory
# 支持多个查找目录
find-in-jars ‘log4j\.properties‘ -d /path/to/find/directory1 -d /path/to/find/directory2

# 帮助信息
$ find-in-jars -h
Usage: find-in-jars [OPTION]... PATTERN
Find file in the jar files under specified directory(recursive, include subdirectory).
The pattern default is *extended* regex.

Example:
    find-in-jars ‘log4j\.properties‘
    find-in-jars ‘^log4j(\.properties|\.xml)$‘ # search file log4j.properties/log4j.xml at zip root
    find-in-jars ‘log4j\.properties$‘ -d /path/to/find/directory
    find-in-jars ‘log4j\.properties‘ -d /path/to/find/dir1 -d /path/to/find/dir2

Options:
  -d, --dir              the directory that find jar files, default is current directory.
                         this option can specify multiply times to find in multiply directory.
  -E, --extended-regexp  PATTERN is an extended regular expression (*default*)
  -F, --fixed-strings    PATTERN is a set of newline-separated strings
  -G, --basic-regexp     PATTERN is a basic regular expression
  -P, --perl-regexp      PATTERN is a Perl regular expression
  -i, --ignore-case      ignore case distinctions
  -h, --help             display this help and exit

注意,Pattern缺省是grep的 扩展正则表达式。

示例

# 在当前目录下的所有Jar文件中,查找出 log4j.properties文件
$ find-in-jars ‘log4j\.properties$‘
./hadoop-core-0.20.2-cdh3u3.jar!log4j.properties

# 查找出 以Service结尾的类
$ ./find-in-jars ‘Service.class$‘
./WEB-INF/libs/spring-2.5.6.SEC03.jar!org/springframework/stereotype/Service.class
./rpc-benchmark-0.0.1-SNAPSHOT.jar!com/taobao/rpc/benchmark/service/HelloService.class
......

# 在指定的多个目录的Jar文件中,查找出 properties文件
$ find-in-jars ‘\.properties$‘ -d ../WEB-INF/lib -d ../deploy/lib | grep -v ‘/pom\.properties$‘
../WEB-INF/lib/aspectjtools-1.6.2.jar!org/aspectj/ajdt/ajc/messages.properties
../WEB-INF/lib/aspectjtools-1.6.2.jar!org/aspectj/ajdt/internal/compiler/parser/readableNames.properties
../WEB-INF/lib/aspectjweaver-1.8.8.jar!org/aspectj/weaver/XlintDefault.properties
../WEB-INF/lib/aspectjweaver-1.8.8.jar!org/aspectj/weaver/weaver-messages.properties
../deploy/lib/groovy-all-1.1-rc-1.jar!groovy/ui/InteractiveShell.properties
../deploy/lib/groovy-all-1.1-rc-1.jar!org/codehaus/groovy/tools/shell/CommandAlias.properties
../deploy/lib/httpcore-4.3.3.jar!org/apache/http/version.properties
../deploy/lib/httpmime-4.2.2.jar!org/apache/http/entity/mime/version.properties
../deploy/lib/javax.servlet-api-3.0.1.jar!javax/servlet/LocalStrings_fr.properties
../deploy/lib/javax.servlet-api-3.0.1.jar!javax/servlet/http/LocalStrings_es.properties
......

参考资料

在多个Jar(Zip)文件查找Log4J配置文件的Shell命令行

时间: 2024-08-30 14:30:13

Java相关脚本的相关文章

【原创】LoadRunner Java Vuser脚本的配置和调试指南

1 编写目的 本文介绍了Loadrunner多负载压力机的配置,并通过测试Java Vuser的数据库连接脚本对配置结果进行了验证,同时对配置过程中遇到的问题和解决的过程进行了记录,关于Java数据库编程的深入学习,大家可以参考其他Java相关教程. 文中的内容大部分来源于本人工作中解决问题的实际经验,另一部分来源于网络,所有内容本人都亲自验证,但难免有疏漏之处,如有疑问,请大家不吝赐教. 文中Loadrunner版本为9.5,操作系统类型为Windows XP和Windows 2003 Ser

SAE Java相关问题小结

转自:http://blog.csdn.net/bhq2010/article/details/8580412 Sae中使用的servlet容器是jetty7.4.x 我想在web.xml中配置一个自己编写的servlet,实现web启动时的初始化工作,但是总是出现各种问题,下面总结了一下在sae中使用java的一些注意事项: 1.在eclipse中开发java web项目时,我总喜欢直接把需要的jar包复制到WEB-INF/lib下,但在开发sae项目时,最好把需要的jar包放到usr lib

重新发现Oracle太美之awr相关脚本简单介绍

大家知道在$ORACLE_HOME/rdbms/admin下,有如下的相关脚本(我的环境为11.2.0.4.2): [[email protected] ~]$ cd $ORACLE_HOME/rdbms/admin [[email protected] admin]$ ls -ltr awr* -rw-r--r-- 1 oracle oinstall  1999 Oct 24  2003 awrrpt.sql -rw-r--r-- 1 oracle oinstall 49166 Sep  1

性能测试相关脚本

1,restime统计响应时间 #!/bin/bash #统计日志响应时间用 if [ $# -lt 1 ]; then echo "at least have one param; " echo "ex: restime a.log b.log *.log" exit 1 fi . lgq_config.sh for((i=1;i<=$#;i++));do opt=`echo ${!i} | grep "^\-F" | awk -F&qu

java相关的面试题目

1.java/c++/ruby/python集中语言的对比 java和c++ java和ruby java和python java相关的面试题目,布布扣,bubuko.com

Java相关配置合集

Java环境变量配置: 1.安装JDK,安装过程中可以自定义安装目录等信息,例如我们选择安装目录为C:\java\jdk1.6.0_08: 2.安装完成后,右击“我的电脑”,点击“属性”: 3.XP选择[高级]选项卡,WIN7选择[高级系统设置] ,然后点击“环境变量”: 4.在“系统变量”中新建变量名为:JAVA_HOME,变量值为:指明JDK安装路径,就是刚才安装时所选择的路径 C:\java\jdk1.6.0_08: 点确定 5.在“系统变量”找到path这个变量,选中后点编辑,鼠标放在变

java ScriptEngine 使用 (java运行脚本文件)

转自:http://www.tuicool.com/articles/imEbQbA Java SE 6最引人注目的新功能之一就是内嵌了脚本支持.在默认情况下,Java SE 6只支持JavaScript,但这并不以为着Java SE 6只能支持JavaScript.在Java SE 6中提供了一些接口来定义一个脚本规范,也就是JSR223.通过实现这些接口,Java SE 6可以支持任意的脚本语言(如PHP或Ruby). 运行第一个脚本程序 在使用Java SE 6运行脚本之前,必须要知道你的

一些Java相关的

都是从<Thinking in Java>英文第四版中摘抄的 _______________________________________________________________________________________________________________________ 变量初始化: The default values are only what Java guarantees when the variable is used as a member of a

老李分享:loadrunner的java user脚本开发

老李分享:loadrunner的java user脚本开发 poptest在性能测试loadrunner的课程里,以web协议为主,同时也讲解其他协议的脚本开发,对于一个性能测试工程师需要掌握一个以上的协议,在这里大家可以看看javauser的脚本开发环境如何搭建. 有对java比较熟悉的朋友,完全可以直接调用javauser来解析协议报文,处理逻辑请求. 脚本开发环境: loadrunner11.0 jdk1.6.32_x86_32 脚本开发 1.选择JavaVuser协议 2.配置java环