星期五 九月 12, 2008
Xinfeng Liu
使用Sun Studio 和Solaris工具解决Java的性能问题
Sun Studio的performance analyzer是能同时对JVM和Java代码的profiling工具,而且比 起那些基于Java的Profiling工具要好用的多。使用Netbeans Profiler时候最好把项目工程放进Netbeans IDE里才好用,否则不方便对被profiling的应用做细粒度的profiling控制,导致大型应用被profiling后运行非常慢。而Sun Studio的performance analyzer对应用性能的影响要小得多,而且使用起来很简便。只要 collect -j on java <arguments> 就可以了。运行完后会生成一个结果数据目录比如test.1.er,然后用analyzer test.1.er 进行图形化的显示和分析,或使用er_print test.1.er进行命令行的显示。
Sun Studio performance analyzer对java profiling结果的分析,可以按三种模式显示: user, expert, machine。因此可以同时分析用户的Java代码和JVM的C++代码。如果你要分析JNI的代码,这个工具更是离不开了。下面是一个例子:
er_print test.1.er
(er_print) limit 20
(er_print) func
Functions sorted by metric: Exclusive User CPU Time
Excl. Incl. Name
User CPU User CPU
sec. sec.
763.864 763.864 <Total>
218.053 218.053 <JVM-System>
44.511 44.581 <Unknown>
33.123 35.195 oracle.jdbc.driver.NumberCommonAccessor.getBigDecimal(int)
21.145 52.287 oracle.jdbc.driver.ClobAccessor.getString(int)
15.401 30.982 java.util.HashMap.get(java.lang.Object)
14.630 20.364 sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(java.nio.CharBuffer, java.nio.ByteBuffer)
13.209 13.259 oracle.jdbc.driver.OracleStatement.prepareAccessors()
13.159 81.157
org.apache.jsp.home_jsp._jspService(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
12.429 15.271 oracle.jdbc.driver.T4C8TTIClob.read(byte[], long, long, boolean, char[])
12.369 16.121 java.lang.String.regionMatches(boolean, int, java.lang.String, int, int)
11.258 11.258 java.lang.String.equals(java.lang.Object)
10.667 10.667 java.lang.Throwable.<init>()
9.517 9.517 oracle.jdbc.driver.T4CConnection.createClobDBAccess()
8.856 30.671 oracle.jdbc.driver.OracleStatement.getColumnIndex(java.lang.String)
6.364 6.364 java.lang.String.indexOf(int, int)
5.844 21.935 java.lang.String.equalsIgnoreCase(java.lang.String)
5.674 5.674 java.nio.CharBuffer.arrayOffset()
4.733 4.733 java.util.Arrays.copyOfRange(char[], int, int)
4.703 4.703 oracle.net.ns.DataPacket.getDataFromBuffer(byte[], int, int)
(er_print) viewmode expert
(er_print) func
Functions sorted by metric: Exclusive User CPU Time
Excl. Incl. Name
User CPU User CPU
sec. sec.
763.864 763.864 <Total>
33.123 35.195 oracle.jdbc.driver.NumberCommonAccessor.getBigDecimal(int)
21.145 52.287 oracle.jdbc.driver.ClobAccessor.getString(int)
19.534 19.534 lwp_yield
17.232 17.232 OopStarTaskQueueSet::peek()
15.401 30.982 java.util.HashMap.get(java.lang.Object)
14.630 20.364 sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(java.nio.CharBuffer, java.nio.ByteBuffer)
13.980 21.855 PhaseChaitin::build_ifg_physical(ResourceArea*)
13.209 13.259 oracle.jdbc.driver.OracleStatement.prepareAccessors()
13.159 81.137
org.apache.jsp.home_jsp._jspService(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
13.129 13.289 IndexSetIterator::advance_and_next()
12.429 15.271 oracle.jdbc.driver.T4C8TTIClob.read(byte[], long, long, boolean, char[])
12.369 16.121 java.lang.String.regionMatches(boolean, int, java.lang.String, int, int)
11.258 11.258 java.lang.String.equals(java.lang.Object)
10.667 10.667 java.lang.Throwable.<init>()
9.517 9.517 oracle.jdbc.driver.T4CConnection.createClobDBAccess()
8.856 30.671 oracle.jdbc.driver.OracleStatement.getColumnIndex(java.lang.String)
7.475 7.475 arrayof_oop_disjoint_arraycopy
6.585 8.736 PhaseChaitin::Split(unsigned)
6.364 6.364 java.lang.String.indexOf(int, int)
(er_print) viewmode machine
(er_print) func
Functions sorted by metric: Exclusive User CPU Time
Excl. Incl. Name
User CPU User CPU
sec. sec.
763.864 763.864 <Total>
111.688 546.232 Interpreter
57.850 60.702 typeArrayKlass::allocate(int,Thread*)
20.324 20.394 sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(java.nio.CharBuffer, java.nio.ByteBuffer)
19.534 19.534 lwp_yield
17.232 17.232 OopStarTaskQueueSet::peek()
16.291 16.291 java.lang.String.regionMatches(boolean, int, java.lang.String, int, int)
14.850 31.062 oracle.jdbc.driver.OracleStatement.getColumnIndex(java.lang.String)
13.980 21.855 PhaseChaitin::build_ifg_physical(ResourceArea*)
13.129 13.289 IndexSetIterator::advance_and_next()
11.638 11.638 java.lang.String.equals(java.lang.Object)
11.588 15.000 java.lang.Object.hashCode()
7.475 7.475 arrayof_oop_disjoint_arraycopy
6.585 8.736 PhaseChaitin::Split(unsigned)
6.545 6.545 java.lang.String.indexOf(int, int)
5.754 5.754 jshort_disjoint_arraycopy
5.484 5.484 flush_callers_register_windows
5.324 16.742 java_lang_Throwable::fill_in_stack_trace(Handle,Thread*)
5.284 5.284 memcpy
5.014 18.333 java.util.Collections$SynchronizedMap.get(java.lang.Object)
有时,单单通过Java本身的工具(如jstat, jmap, jinfo, jconsole, java thread dump等)不足以分析出问题,还是需要依靠操作系统的工具来定位。比如pstack, prstat -mL -p <pid>,pmap -xs, DTrace等。假如通过prstat发现Java应用总是不能充分利用CPU,可以通过一个简单的DTrace脚本来找出原因:
offcpu.d
--------
#!/usr/sbin/dtrace -s
off-cpu
/pid == $target/
{
@[jstack(20,200)]=count();
}
tick-2sec
{
trunc(@,10);
printa(@);
clear(@);
}
# ./offcpu.d -p <java process id>
无论你愿不愿意承认,总之Java在Solaris上运行的最好,道理就不用说了。
Posted at 02:11上午 九月 12, 2008 by xinfeng liu in Java & JES | Comments[0]
Java的内存泄漏问题
查找Java的内存泄漏一直是件困难的事情。一些基于instrument的工具无论是商业的还是开源的也都不是很有效,因为instrument对被测系统的影响太大,难以重现问题。尤其是对大型的应用以及生产系统上的调试帮助不大。
我一年多前写过一片这方面的文章,主要是讲Java内存泄漏常见的原因以及Java SE6提供的一些工具来帮助查找内存泄漏。但是临到发表时 ,我自己提出把它撤了下来,原因是觉得现有的这些工具还是不足够来百分之百地定位问题。现在想想还是把它以非正式的方式发出来比较好,希望能对人有所启发,下载。另外,netbeans的profiler现在应该有了长足的进步,只是自己没时间去研究,不知道有没有人能分享这方面的经验。
-xinfeng
Posted at 10:58下午 六月 11, 2008 by xinfeng liu in Java & JES |
如何分析Java虚拟机死锁
我发现现在网上没有好好讲这个的,少数的几篇文章都是大谈自己的工具,却没把方法讲清楚。我决定以我以前碰到的case为例写一篇来分享。
到目前为止,我认为分析Java代码问题的最有效的工具仍然是java thread dump。
[Read More]Posted at 05:23上午 十月 01, 2006 by xinfeng liu in Java & JES | Comments[6]
如何让EJB客户端从Internet访问内网的Sun应用服务器
在Web2.0的时代提这东西实在有点过时,但它却是个困扰了我很久的问题,而且也确实有些用户要这样用。
[Read More]
Posted at 05:50上午 八月 13, 2006 by xinfeng liu in Java & JES |
看看用jMaki 和 Netbean5.5 开发互动性的web应用有多简单!
使用了Ajax的控件。不多说了,看看demo吧。
https://ajax.dev.java.net/screencast/jMaki/jMaki.html
Posted at 06:34下午 六月 06, 2006 by xinfeng liu in Java & JES | Comments[3]
通过软件实现Access Manager的负载均衡设置
还是以前写的文章,是英文的。http://developers.sun.com/prodtech/identserver/reference/techart/load-balancing.html
Posted at 12:47上午 四月 12, 2006 by xinfeng liu in Java & JES |
Access Manager的客户端证书认证
把以前写的文章整理一下。以后写东西先放到blog上供大家review。http://isv.sun.com.cn/techdocs/0601/index.jsp
Posted at 12:41上午 四月 12, 2006 by xinfeng liu in Java & JES |
如何知道Java Class文件的Java版本
Java Class的版本信息位于class文件的头部。
-bash-3.00$ od -x Hello.class|more
输出大概象这样:
0000000 feca beba 0000 3100 2200 000a 0006 0914
.....
Look at 5th-8th bytes, this example is:
0000 3100
3100 is major version: 31 is jdk1.5, 30 is jdk1.4, 2F is jdk1.3...
0000 is minor version.
(Note: 1st-4th is Java magic number, it is always "cafebabe" :-))
You may find the version of some class files compiled by javac of jdk1.4 is '2e', it means the class file can be run by JDK1.2 or later, but it cannot be run by JDK1.1.
Thanks,
Xinfeng
Posted at 06:48下午 四月 05, 2006 by xinfeng liu in Java & JES |
