LMAX

No Comments

忘了是谁在微博上赞叹了一句LMAX,于是乎去看了看Martin Fowler老爷子的这篇“The LMAX Architecture”。

看过以后实际上觉得也很坦然,不管是谁赞叹的LMAX,终归是一个做Java很久的人。为了找到这位的原话,我也特意又去微博搜了搜,看到了很多做Java的人在同样赞叹LMAX。实际上只要看看Martin的这文章就能明白,核心实际和Java关系不大,倒是吸收了web界一直以来的很多做法、算法和架构,最终用Java实现了一套而已。我几乎能看到Martin老爷子星星眼的样子… 当然老爷子自己也还是很有自知之明的,比如这句:

Many programmers, and I confess I fall into this camp, don’t have much mechanical sympathy for how programming interacts with hardware.

还有之前一句以脚注出现的:

I rarely think about which collection implementation to use. This is perfectly reasonable when you’re not in performance critical code. Different contexts suggest different behavior.

哎,两句话就暴露出做(Java)企业应用以及企业应用架构设计的人一直以来的问题了吧。在现在web开发技术这样一日千里的发展的情况下,企业应用那套,虽然在设计和工程上仍旧有些许价值,但也真是有点儿明日黄花了,尤其涉及到性能、吞吐量这些。

算了,没太多吐槽的想法。Java作为一个平台也有些苦涩,特别讲求高性能的场合下只要有牛人加持的话几乎都不会选Java,但是JVM作为Java平台最重要的一个组件,又积蓄着很多力量多年的成果,尤其GC方面,而且Java语言又是那么地没有门槛,感觉长期看来在必须考虑人力开销的项目和产品里,Java也还是一直会是个不错的备选。

P.S.,LMAX开源出来的disruptor,各位看那个logo熟悉不 :D

[浅读openjdk7] 1. 构建openjdk7 @Mac

6 Comments

我这么寻思啊,在各种伟大的Linux这种对开发人员这么友好的OS们里面,一切构建方面的问题都是纸老虎。也因为目前手里没方便的Linux机器(其实公司里有一台,外加跑着blog的VPS,就是嫌麻烦…),所以怎么在Linux上面折腾build openjdk7就不废话了,应该比起openjdk6来说不会复杂太多的吧,参考 [浅读openjdk6] 1. 构建openjdk6 。在Windows上嘛,谁乐意折腾谁折腾去吧…反正build完了debug时也不是很爽。

其实今时今日Mac用户也算赶上好时候了,因为Oracle和Apple关于OpenJDK项目合作的事情似乎进行还不错,所以Oracle这边厢似乎也投入了不少,最明显的,NND终于看到像样的官方指导了!—— Mac OS X Port。这么一来build完全不构成任何问题了,ALLOW_DOWNLOADS=true 了以后连一些依赖项都会被自动下载了…

但是,我还是碰见了一个问题:那是编译corba子项目下自动生成的代码的时候,因为文件编码的问题会失败——就这么一个问题,也在 OpenJDK for Mac OS X 这篇日本语blog里描述并解决了,而且还被人在 Mac OS X Port 这篇wiki上主动留了下链接…就是那个通过设置环境变量 _JAVA_OPTIONS=-Dfile.encoding=ASCII 搞定的那部分。至于这位 dolduke 提到的其他几个问题我反正还没遇到。

感慨现在命真好的同时也确实没神马成就感了。

P.S.,春天晚上还是比较冷啊,build一下openjdk有助于取暖。

[浅读openjdk7] 0. 获取openjdk7源代码

1 Comment

呃,我自己都觉得很惭愧… 距离那篇 [浅读openjdk6] 0. 获取openjdk6源代码 过去了要2年了吧,期间总算不出意外地没有怎么继续那个系列。草稿箱里累积了大概5篇,顺着main函数开始的一些理解,结果还是没能坚持下来,哪天都删掉好了…

最近身边一个小朋友也开始看openjdk6了,加上网上某些著名人士年前也都零零散散地开始看代码并且发布了些blog,各种奋发图强人士让我感觉真是情何以堪。想了想,不行我也继续看吧,只不过目标换到了openjdk7,不是为了别人看6我看7显得多牛逼,而是对project coin那些小改动比较感兴趣。

结果,因为现在换了MacBook Pro了,不再频繁用Linux,照着自己以前在Linux下的方法做果然没能成功(呃,简直是一定的吧,尤其我也不是MacPorts用户),上网搜了搜,发现一篇 Build OpenJDK Java 1.7.0 on Mac OS X 10.5,已经装过MacPorts的权当参考吧,其实和Linux下差不多了。不过我不老喜欢MacPorts那样的东西,原先也许会喜欢吧,原汁原味的感觉,但是到了要决定是不是真要搞到自己机器上来的那一霎那,就觉得它太过臃肿了,转去用Homebrew了,虽然我也不是ruby用户…

继续搜,然后发现,好像年初的时候openjdk在BSD port的基础之上有了专门的mac os x port项目,见 http://mail.openjdk.java.net/pipermail/macosx-port-dev/2011-January/000007.html ,Apple员工发的,也算是Oracle宣称的和Apple合作提高OpenJDK在Mac机器上的覆盖面吧——这点来说Oracle至少及格了,借用开源的openjdk和Apple这样的商业公司达成了某些协议,阻止乔不死大爷试图在Mac上扼杀Java的企图。

所以现在如果在Mac OS X上想要拿到openjdk7的代码,需要clone专门的那个mac os x port项目的代码库:


hg clone http://hg.openjdk.java.net/macosx-port/macosx-port
cd macosx-port
chmod a+x get_source.sh
./get_source.sh

这样这个脚本会自动去clone位于macosx-port项目下的corba,jaxp,jaxws,langtools,jdk和hotspot这些子项目,和标准的其他平台上的openjdk7是一样的。看脚本的代码应该是不再需要mercurial的forest那个插件了,不过里面也写到了fclone分支,不知道到底什么动机,所以为求保险,建议还是安装forest插件,但是最开始的老版的forest插件已经不维护了,更新的在 http://hg.akoha.org/hgforest/,github上也看到过一个fork,说是提供了一些bug fix,不过我没试过。对于Linux和Windows来说,hg fclone依旧,顶层库的URL为http://hg.openjdk.java.net/jdk7/jdk7/

此外,Mac上XCode据说也要安装,最低要3.2.x。不知道对于拿代码来说是不是必需的,不过后期做build肯定是必备无疑。

最后,以./get_source.sh运行输出结尾。


iusr-mbp:macosx-port iusr$ ./get_source.sh
# Repos:  corba jaxp jaxws langtools jdk hotspot
Starting on corba
Starting on jaxp
Starting on jaxws
Starting on langtools
Starting on jdk
Starting on hotspo
t# hg clone http://hg.openjdk.java.net/macosx-port/macosx-port/corba corba
requesting all changes
adding changesets
adding manifests
adding file changes
added 333 changesets with 3221 changes to 1379 files
updating to branch default
1357 files updated, 0 files merged, 0 files removed, 0 files unresolved
# exit code 0
# hg clone http://hg.openjdk.java.net/macosx-port/macosx-port/jaxp jaxp
requesting all changes
adding changesets
adding manifests
adding file changes
added 252 changesets with 2188 changes to 1984 files
updating to branch default
18 files updated, 0 files merged, 0 files removed, 0 files unresolved
# exit code 0
# hg clone http://hg.openjdk.java.net/macosx-port/macosx-port/jaxws jaxws
requesting all changes
adding changesets
adding manifests
adding file changes
added 242 changesets with 6427 changes to 3002 files
updating to branch default
18 files updated, 0 files merged, 0 files removed, 0 files unresolved
# exit code 0
# hg clone http://hg.openjdk.java.net/macosx-port/macosx-port/langtools langtools
requesting all changes
adding changesets
adding manifests
adding file changes
added 945 changesets with 12323 changes to 4546 files
updating to branch default
4225 files updated, 0 files merged, 0 files removed, 0 files unresolved
# exit code 0
# hg clone http://hg.openjdk.java.net/macosx-port/macosx-port/hotspot hotspot
requesting all changes
adding changesets
adding manifests
adding file changes
added 2287 changesets with 20293 changes to 4202 files
updating to branch default
3903 files updated, 0 files merged, 0 files removed, 0 files unresolved
# exit code 0
# hg clone http://hg.openjdk.java.net/macosx-port/macosx-port/jdk jdk
requesting all changes
adding changesets
adding manifests
adding file changes
added 3767 changesets with 54877 changes to 20574 files
updating to branch default
19580 files updated, 0 files merged, 0 files removed, 0 files unresolved
# exit code 0
# Repos:  . ./corba ./hotspot ./jaxp ./jaxws ./jdk ./langtools
Starting on .
Starting on ./corba
Starting on ./hotspot
Starting on ./jaxp
Starting on ./jaxws
Starting on ./jdk
Starting on ./langtools
# cd . && hg pull -u
pulling from http://hg.openjdk.java.net/macosx-port/macosx-port
searching for changes
no changes found
# exit code 0
# cd ./hotspot && hg pull -u
pulling from http://hg.openjdk.java.net/macosx-port/macosx-port/hotspot
searching for changes
no changes found
# exit code 0
# cd ./corba && hg pull -u
pulling from http://hg.openjdk.java.net/macosx-port/macosx-port/corba
searching for changes
no changes found
# exit code 0
# cd ./langtools && hg pull -u
pulling from http://hg.openjdk.java.net/macosx-port/macosx-port/langtools
searching for changes
no changes found
# exit code 0
# cd ./jaxws && hg pull -u
pulling from http://hg.openjdk.java.net/macosx-port/macosx-port/jaxws
searching for changes
no changes found
# exit code 0
# cd ./jaxp && hg pull -u
pulling from http://hg.openjdk.java.net/macosx-port/macosx-port/jaxp
searching for changes
no changes found
# exit code 0
# cd ./jdk && hg pull -u
pulling from http://hg.openjdk.java.net/macosx-port/macosx-port/jdk
searching for changes
no changes found
# exit code 0

[浅读openjdk6] 1. 构建openjdk6

No Comments

接上篇,当openjdk6的代码库已经用mercurial clone/fclone完毕之后,就可以构建openjdk6了。当然构建与阅读源代码没有太大关系,只是如果日后还要做hack的话,总要通过构建和测试来检查、调试自己的hack不是,所以了解openjdk6的构建方法还是有点必要的。
基本上,代码库根目录下的README-builds.html中的讲解已经很到位了,我这里再简要地啰嗦一下整个步骤,权当个中文翻译好了。
  1. 必需的应用程序:gcc 4,g++ 4,GNU make (>3.80),m4 (>1.4.4)。以及README-builds.html中指定的很多个开发包(dev)。我的操作系统是Ubuntu 8.10,内核版本为2.6.27-14,按照README-builds.html的包依赖关系,一下子:
    sudo apt-build install binutils cpp libfreetype6-dev g++ cpp-4.1 g++-4.1 gcc-4.1 gcc-4.1-base libstdc++6-4.1-dev gawk gcc libasound2-dev libc6 libc6-dev libc6-i686 libcupsys2-dev libgcrypt11-dev libgnutls-dev libgnutls26 libgpg-error-dev libice-dev liblockfile1 libopencdk10 libpopt-dev libsm-dev libtasn1-3-dev libx11-dev libxau-dev libxaw7-dev libxdmcp-dev libxext-dev libxi-dev libxmu-dev libxmu-headers libxmuu-dev libxp-dev libxpm-dev libxrandr-dev libxt-dev libxtrap-dev libxtst-dev libxv-dev m4 make ssl-cert x-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev x11proto-randr-dev x11proto-record-dev x11proto-trap-dev x11proto-video-dev x11proto-xext-dev zlib1g-dev

    就好了。我的机器里其实已经装了libstdc++6-4.3-dev以及g++-4.3,不过保险起见还是把g++ 4.1以及libstdc++6 4.1的东西搞进来了,尊重一下README-builds.html,也顺便给自己少找些麻烦——后来测试的时候还真发现用libstdc++6 4.3或者g++ 4.3的话会编译失败,大概看了看错误信息,结论是以我现在的c++水平如果要把它port到4.3的话还是暴有难度的…嗯,那就4.1吧,听话的孩子有糖吃。

  2. 参照README-builds.html,有2个环境变量是必需的,当然这俩环境变量的值指向的目录也不是乱来的:
    • Bootstrap JDK:README-builds.html自己都说了,编译openjdk6的时候还需要一个已有的jdk6是很那啥的。没办法,估计语言发展起来之后需要自己来编译自己的某一部分也不是很罕见的事情吧。我的系统里已经装了SUN的jdk6,所以,ALT_BOOTDIR=/usr/lib/jvm/java-6-sun。
    • JDK binary plugins:这东西还是个新鲜玩意儿,以前是没听说过。照着README-builds.html里的指示,按图索骥到最新发布的jdk 6 binary plugins:http://download.java.net/openjdk/jdk6/promoted/b14/jdk-6-ea-plug-b14-linux-i586-25_nov_2008.jar。这是个可执行jar文件,java -jar一下,accept一下条款之类的东西,指定个目录就可以安装了。安装完成后,在安装目录里会看到一个openjdk-binary-plugs的子目录,结构和普通jdk一致,内容只有两个文件:LICENSE和jre/lib/rt-closed.jar。rt-closed.jar的内容没什么惊喜,一堆SUN自己的SNMP功能的支持类,光看这文件名就知道肯定是不方便开源的东西。不管它的内容:ALT_BINARY_PLUGS_PATH=~/projects/openjdk/jdk6-bin-plugins/openjdk-binary-plugs/ 。
    • 其他的几个环境变量我是没有再手动设置,估计debian系的系统里,那些dev包安装妥当之后也不用再自己设了。

然后,终于可以开始make了,先来make sanity一下,确认当前配置没问题,没问题的话就可以直接跑make了。所有c/c++的代码无疑都是gcc、g++来编译的,其他诸如corba、jaxp、jaxws是单独用javac以及ant编译的,我用的机器上已经装好了ant 1.6.5,编译jaxp和jaxws时也没出什么问题。整个make过程在我这台P4 2.4G MHz 2G RAM的机器里花费掉了…差点儿一个小时…中间看到”linking vm…”的时候我几乎要哭出来了…
make成功后,build/目录下包括所有编译、链接出来的可执行文件以及jar包,还有javadoc。里面的j2re-image和j2sdk-image分别是…jre以及jdk,嗯,废话,是吧。进到bin目录下./java -version一下:

iusr@wisdom:~/projects/openjdk/jdk6/build/linux-i586/bin$ ./java -version
openjdk version “1.6.0-internal”
OpenJDK Runtime Environment (build 1.6.0-internal-iusr_18_mar_2009_16_32-b00)
OpenJDK Client VM (build 11.0-b17, mixed mode)

Yay!


Update: 到一台默认语言设成中文的ubuntu 8.10上重make一次,结果出错了…有3个注意事项要更新一下:
  1. g++、libstdc++6 dev包的版本问题。如果几个版本共存的话,确保g++-4.1在PATH的最前面能被最先找到。这个比较好解决,而且一旦g++版本正确的话也会确保include路径是对应的libstdc++6的头文件库。小问题。
  2. make之前要unset JAVA_HOME。这个环境变量如果存在的话make sanity会报错,错误信息也很明显,所以,同样是小问题。
  3. LANG=C。无论export出去还是运行make,一定确保LANG兼容英语,否则会出现很奇异的错误…
  4. apt-build install libmotif-dev 。这个忘记了很不应该,因为我用awesome,所以还特别地在.profile里export AWT_TOOLKIT=MToolkit了的。

其他的诸如gawk、m4之类居家旅行必备的东西,如果落下没说的话还请自己装好。

[浅读openjdk6] 0. 获取openjdk6源代码

4 Comments

最近几天在抽空看openjdk6的源代码。总觉得如果打算干很久java的话,光靠看tutor、doc、reference始终有种底气不足的感觉;src.zip里的东西可以随用随看,但各种本地方法调用以及src.zip不方便包含的类的源代码都是平日在eclipse里开发时很少会花时间看的,但这一部分往往最能决定一个java应用程序的性能。其实预谋了很久了,大概多半年到一年前就有这打算了,可始终没什么空闲,杂事也很多。
OpenJDK老窝在http://openjdk.java.net/。记得早先mustang、dolphin还都在dev.java.net这个域下,而OpenJDK直接挂在java.net下,身份自然特殊。不管别人怎么看,我是想目前先看jdk6的代码,因为日常开发正在用,jdk6也是SUN目前的主打版本,VM特性和API也更稳定,相比之下,jdk7还在密集开发之中,平日看看各种相关人员的blog,新特性、新API也是隔一阵儿就来一个,现在追起来肯定会很累,虽说jdk7也肯定是以后的主流。
获取openjdk6的代码其实也不复杂,尤其是download source bundle的方式,当然也更没劲一些——我(们)的目标是:往死里折腾。
折腾当然有折腾的好处。当你clone了整个一个mercurial forest以后,查看变更记录是了解各种特性、API以及bug fix的最直接的途径,比看什么release notes都管用,而且适合fork出自己hack过的版本——听着很吓人,其实一个hack不见得必须是一个很BT的很完善的东西,那样的话基本成了添加一个feature了,还不如去盯OpenJDK社区啥时候再出Innovators’ Challenge的时候去赚些钱;很多时候hack都是临时解决一些小问题,看上去甚至会觉得有些dirty。
openjdk的源代码采用mercurial做版本管理。Mercurial也是个分布式的版本控制系统,优点是跨平台,缺点是忒慢了点儿,用惯了git尤其没法容忍管理些源代码都慢吞吞的;基本上我也只是用它来拿openjdk的代码,目前还罕见有多少我感兴趣的项目使用mercurial的,所以也没动机去深入学习一下。openjdk6的代码位于http://hg.openjdk.java.net/jdk6/jdk6/,是一个mercurial forest——一大堆源代码tree在一起就形成了源代码forest。配置mercurial以及安装那个forest插件的过程参考一下http://openjdk.java.net/guide/repositories.html应该可以搞定,不是什么大件事。有了mercurial+forest插件以后,找个干净目录来fclone一下:

iusr@wisdom:~/projects/openjdk$ hg fclone http://hg.openjdk.java.net/jdk6/jdk6/
[.]
requesting all changes
adding changesets
adding manifests
adding file changes
added 27 changesets with 63 changes to 29 files
updating working directory
29 files updated, 0 files merged, 0 files removed, 0 files unresolved

[corba]
requesting all changes
adding changesets
adding manifests
adding file changes
added 26 changesets with 1439 changes to 1376 files
updating working directory
1371 files updated, 0 files merged, 0 files removed, 0 files unresolved

[hotspot]
requesting all changes
adding changesets
adding manifests
adding file changes
added 28 changesets with 7862 changes to 3278 files
updating working directory
2964 files updated, 0 files merged, 0 files removed, 0 files unresolved

[jaxp]
requesting all changes
adding changesets
adding manifests
adding file changes
added 26 changesets with 2021 changes to 1975 files
updating working directory
1973 files updated, 0 files merged, 0 files removed, 0 files unresolved

[jaxws]
requesting all changes
adding changesets
adding manifests
adding file changes
added 29 changesets with 4864 changes to 2867 files
updating working directory
2583 files updated, 0 files merged, 0 files removed, 0 files unresolved

[jdk]
requesting all changes
adding changesets
adding manifests
adding file changes
added 97 changesets with 41623 changes to 17063 files
updating working directory
16829 files updated, 0 files merged, 0 files removed, 0 files unresolved

[langtools]
requesting all changes
adding changesets
adding manifests
adding file changes
added 40 changesets with 6616 changes to 3018 files
updating working directory
3012 files updated, 0 files merged, 0 files removed, 0 files unresolved

fclone是forest插件提供的命令,如果forest插件没有配置妥当的话mercurial会提示无法处理fclone这个命令的。等mercurial慢吞吞地把代码下载回来后,折腾的第一步就完成了。当然如果只关注openjdk6的某一模块,比如hotspot,可以单独clone这一个tree。基本上hotspot模块是每个人都感兴趣的,jdk模块次之,其他的corba、jaxp、jaxws之流也不算什么rocket science。考虑到模块大小的话:

iusr@wisdom:~/projects/openjdk$ du -s -B M jdk6/ jdk6/*
542M jdk6/
1M jdk6/ASSEMBLY_EXCEPTION
20M jdk6/corba
63M jdk6/hotspot
37M jdk6/jaxp
35M jdk6/jaxws
349M jdk6/jdk
39M jdk6/langtools
1M jdk6/LICENSE
1M jdk6/make
1M jdk6/Makefile
1M jdk6/README 1M jdk6/README-builds.html 1M jdk6/THIRD_PARTY_README 1M jdk6/TRADEMARK

大概要准备>600M的空间吧,这年头应该谁都不在乎这点儿地方了吧。
OpenJDK社区的代码仓库索引页位于http://hg.openjdk.java.net/,对其他项目感兴趣的话可以自行clone/fclone。
开始折腾前还要铭记一点:大部分openjdk6的源代码是以GPL v2许可的,部分基于其他开源项目的代码还维持其许可证不变,此外还有部分二进制模块使用的是OpenJDK二进制文件许可证。如果真折腾出来好东西了,别忘了回馈社区,没有人家夯下的基础,这一切都不可能完成。

产业政治?

No Comments

continuation,对这个东西很久之前开了个头就没再深入,晚上又拾起来看了下,也算continuation了吧。jsr 315敢情被apache sf驳了,而且是因为很扯淡的产业政治问题,但愿不要难产,tomcat拿起来还算没门槛一些,想改哪里都好改。

On 2009-01-12 Apache Software Foundation voted No with the following comment:
The Apache Software Foundation's vote is based on the point of view that this spec lead – Sun – is in violation of the JSPA

http://www.apache.org/jcp/sunopenletter.html

and therefore shouldn't be allowed to start or continue another JSR until the above matter is resolved.

This vote is not a comment on the technical merits of the JSR.  If not for the issue of the spec lead, the ASF would have otherwise voted "yes".

过年期间本想更新下那个纠结的问题的进展,八成是fix了,而且是我们自己的问题。在这个问题上我也算费了不少心思,也积累了很多,只不过对公司的贡献还不如US那里的人坐着review一下代码。嘴上拿不熟悉这新家酿框架以及从另外一版port过来又做了些山寨修改的代码当作借口,实际上最主要的还是态度问题,因为主观上就没想我们的代码能搞坏下面tomcat和apache的行为。回头好好总结。

Locating the Guilty Java Threads

6 Comments

A summary of my recent experience with resolving an 100% CPU utilization issue.

We know well that in Java 5 and above we have the mighty java.lang.management.ThreadMXBean which is able to give us almost all ordinary diagnostics information of a given thread, except more detailed information that only debuggers are able to tell. However, such information is implementation/vendor dependent and some information, like CPU time measurement, might be disabled by default, and moreover, in my humble opinion, these information may be not very accurate since they are reported by the JVM itself, not by the OS.

Luckily, almost every popular OS supports some means of measurements down to the threading level, and on the Java side, we have the thread dump (of course, also in popular JVM implementations). I’m here taking Ubuntu, Windows XP with SUN JVM (5.0 for Windows and 6.0 for Linux) as an example. This example demonstrates the process to find the thread that is utilizing unusual amount of CPU time in a Tomcat instance hosting a very simple web application.

When there’s something wrong caused by the JVM, say, similarly, it simply occupies all CPU time, you can always find the guilty threads by doing so:
1. Getting threading information from the OS.
In most Linux distros, a single ps command can handle this. For instance, ps H -eo user,pid,ppid,tid,time,%cpu,cmd –sort=-%cpu , will print out all the processes and their created threads, sorted by the percentage of overall CPU utilization. We can always RTFM for more information about *nix commands;)
ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=-%cpu
In Windows, however, getting threading information for a process might be harder. I suggest using Process Explorer, which is the most easy to use tool amongst other equivalents.

First of all, open the “Properties” dialog of the JVM process.

See Process Properties

Next, click on the “Threads” tab to see threads of the process. You can see that they are sorted by CPU utilization by default.

Enumerating Process Threads
(I have a dual core CPU and this thread is occupying a whole core)
2. Getting a thread dump from JVM.
This task should be easier for us as Java developers;) In Linux we use kill -3 PID,
Producing Heap Dump in my Ubuntu Linux
(I was running less logs/catalina.out after the thread dump, because I wrongly started Tomcat by bin/catalina.sh start instead of bin/catalina.sh run. Never mind)
and in Windows we can simply hit Ctrl+Break in the console window that is running the JVM process.
Producing Heap Dump in Windows
3. Finding out the Java thread from
Usually the thread ID printed by the OS are in decimal format, and this value needs to be converted into a hexadecimal. And next, no other magic other than finding “nid=xxx” terms in the thread dump. See highlighted parts:

7772=0x1E5C

Thread ID 0x1e5c

2148=0×864
Thread ID 0x864
Yep, that’s it, test.Test.test();. I’m not going to amuse you by posting the source of test.Test.test(), since it’s no more than an infinite loop:D

Regards and hope this helps.

Start the Eclipse TPTP Profiling Agent under the Standalone Mode in a Linux Box

No Comments

I did this long ago. Since I’m not required to do it repeatedly, it took me another 15 minutes to get warmed up. This time I’m recording the procedures here as a preparation for tomorrow’s exploration on why the hell that tomcat instance was taking so long to start up.

  1. JVM arguments: -XrunpiAgent:server=standalone,file=/home/iusr/tc.trcxml,profile=/home/iusr/piAgent.options,filters=/home/iusr/piAgent.filters. It’s convenient to export all this twittering to JAVA_OPTS which is used by tomcat to pass to JVM;
  2. Adjust the LD_LIBRARY_PATH environment variable to include directory “<eclipse_install_or_ext_point>/plugins/org.eclipse.hyades.execution.<OS>.<CPU_ARCH>_<VERSION>”, e.g., in my Edgy box it’s “/usr/local/eclipse-extension/eclipse.org/tptp/eclipse/plugins/org.eclipse.hyades.execution.linux.x86_4.2.2.v200701141614″;
  3. Compose the profile configuration, filters configuration. Refer to http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.tptp.platform.doc.user/ref/rsaproffilt.htm and http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.tptp.platform.doc.user/tasks/teprofsa.htm for the proper format.
  4. Run the java class, of course:)

A profile configuration consists several entries, here’s an example (“^\*.*$” lines stand for comments):

* all | none
MONITOR_MODE = all
* true | false
FILTERS = true
* none | deletes | frees | moves | deletesAndMoves | movesAndFrees
TRACK_GC_EVENT_TYPES = movesAndFrees
* static | relocatable | staticAndRelocatable
ID_STYLE = staticAndRelocatable
* true | false
* OPTIONS = false
TIMESTAMPS = true
METHOD_COUNTS = true
OBJ_ALLOC_IS_ARRAY = true
* none | normal | boundary | contiguous | boundaryAndContiguous
STACK_INFORMATION = contiguous
* true | false
* TICKET = true
* full | none | noObjectCorrelation
TRACE_MODE = full
* true | false
* TRACE_ID_REFS = true

Apparently this configuration requires much work to do, so my CPU got 99% utilized just now:P.
The filters configuration is more straightforward, only a wildcard string indicating the desired packages or classes, another wildcard string indicating the methods, and a directive indicating the whether matching packages or classes are to be included or excluded. Here’s an example:

package = com.*
method = *
mode = INCLUDE

Since some subtle differences amongst different Linux distros and versions, the configuration above varies. I once saw a web page saying it’s necessary to add the directory “<eclipse_install_or_ext_point>/plugins/org.eclipse.hyades.execution.<OS>.<CPU_ARCH>_<VERSION>” not only to LD_LIBRARY_PATH but also to PATH. I haven’t tried this out yet, since adding it to LD_LIBRARY_PATH works every time and appears to be more reasonable. Particularly, if the piAgent failed to get loaded or started, take a look at the output of `ldd <eclipse_install_or_ext_point>/plugins/org.eclipse.hyades.execution.<OS>.<CPU_ARCH>_<VERSION>/libpiAgent.so` to check out if there’s anything dependent missing.
Whoa, I cannot help starting the agent on our main testing machine to find out what the hell contributed to the latencies.

潜水偶得

No Comments

潜水于dev-tomcat这个列表已经好久了,平时只有仰慕的份,不敢在上面废话。
不过最近考古翻腾svn commit信件,发现Remy和Mladen两位老大实在太有意思了。比较典型的可以看这个:http://mail-archives.apache.org/mod_mbox/tomcat-dev/200611.mbox/%3c20061129125924.334571A9846@eris.apache.org%3e, 闲的无聊的话可以按Thread右边的>>一路点过去。
还发现ant-dev里涉及到svn commit的信件好像大部分都和Java无关一样,sigh,几乎都是讨论如何能更developer friendly的话题。
mailing list, newsgroup, 赫赫,web?唉。

Oops

No Comments

Programmer:
// muhaha
String test = “blahblahblah”;
String str = new String(test + ” is OK” + “, damn it.”);

Compiles to:
JVM INSTR start_warning “Alert! Eden generation, you’ll be shooted with a bunch of temporary Objects!” ;
0:ldc1 #16 <String “blahblahblah”>
2:astore_1
3:new #18 <Class java.lang.String>
6:dup
7:new #20 <Class java.lang.StringBuilder>
10:dup
11:aload_1
12:invokestatic #22 <Method java.lang.String java.lang.String.valueOf(java.lang.Object)>
15:invokespecial #26 <Method void StringBuilder(java.lang.String)>
18:ldc1 #29 <String ” is OK”>
20:invokevirtual #31 <Method java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String)>
23:ldc1 #35 <String “, damn it.”>
25:invokevirtual #31 <Method java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String)>
28:invokevirtual #37 <Method java.lang.String java.lang.StringBuilder.toString()>
31:invokespecial #41 <Method void String(java.lang.String)>
34:astore_2
JVM INSTR start_warning “Please the GC thread heal our poor Eden…” ;

Older Entries