﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-庄周梦蝶-随笔分类-工具和命令</title><link>http://www.blogjava.net/killme2008/category/49226.html</link><description>生活、程序、未来</description><language>zh-cn</language><lastBuildDate>Fri, 15 Jun 2012 20:27:07 GMT</lastBuildDate><pubDate>Fri, 15 Jun 2012 20:27:07 GMT</pubDate><ttl>60</ttl><item><title>Clojure世界：利用HouseMD诊断clojure</title><link>http://www.blogjava.net/killme2008/archive/2012/06/15/380822.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 14 Jun 2012 18:52:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2012/06/15/380822.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/380822.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2012/06/15/380822.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/380822.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/380822.html</trackback:ping><description><![CDATA[<br />
&nbsp; &nbsp; <a href="https://github.com/zhongl/HouseMD">HouseMD</a>是淘宝的聚石写的一个非常优秀的Java进程运行时诊断和调试工具，如果你接触过btrace，那么HouseMD也许你应该尝试下，它比btrace更易用，不需要写脚本，类似strace的方式attach到jvm进程做跟踪调试。<br />
<br />
&nbsp; &nbsp; 基本的安装和使用请看这篇文档《<a href="https://github.com/zhongl/HouseMD/wiki/UserGuideCN">UserGuide</a>》，恕不重复。以下内容都假设你正确安装了housemd。<br />
<br />
&nbsp; &nbsp; 本文主要介绍下怎么用housemd诊断跟踪clojure进程。Clojure的java实现也是跑在JVM里，当然也可以用housemd。<br /><br />
&nbsp; &nbsp; 我们以一个简单的例子开始，假设我们有如下clojure代码：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->(loop&nbsp;[x&nbsp;1]<br />
&nbsp;&nbsp;(Thread/sleep&nbsp;1000)<br />
&nbsp;&nbsp;(prn&nbsp;x)<br />
&nbsp;&nbsp;(recur (inc x)))</div>
<br />
&nbsp; &nbsp; 这段很简单，只是间隔一秒不断地打印递增的数字x。我们准备用housemd跟踪这个程序的运行，首先运行这个程序，你可以用lein，也可以直接java命令运行：<br />
<div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
-->java&nbsp;-cp&nbsp;clojure.jar&nbsp;clojure.main&nbsp;test.clj</div>
<br />
&nbsp; &nbsp; 运行时不断地在控制台打印数字，通过jps或者ps查询到该进程的id，假设为pid，使用housemd连接到该进程：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
-->housemd&nbsp;&lt;pid&gt;</div>
&nbsp; &nbsp; 顺利进入housemd的交互控制台，通过help命令可以查询支持的命令：<br />
<br />
<div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->housemd&gt;&nbsp;help<br />
<br />
quit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;terminate&nbsp;the&nbsp;process.<br />
help&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display&nbsp;<span style="color: #0000FF; ">this</span>&nbsp;infomation.<br />
trace&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display&nbsp;or&nbsp;output&nbsp;infomation&nbsp;of&nbsp;method&nbsp;invocaton.<br />
loaded&nbsp;&nbsp;&nbsp;&nbsp;display&nbsp;loaded&nbsp;classes&nbsp;information.</div>
<br />
&nbsp; &nbsp; 要用housemd调试clojure，你需要对clojure的实现有一点点了解，有兴趣可以看过去的一篇blog《<a href="http://www.blogjava.net/killme2008/archive/2010/07/11/325775.html">clojure hacking guide</a>》，简单来说，clojure的编译器会将clojure代码编译成java类并运行。对于JVM来说，clojure生成的类，跟java编译器生成类没有什么不同。<br />
&nbsp; &nbsp; 具体到上面的clojure代码，会生成一个名为<strong>user$eval1</strong>的类，user是默认的namespace，而eval1是clojure编译器自动生成的一个标示类名，通过<strong>loaded</strong>命令查询类的加载情况：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->housemd&gt;&nbsp;loaded&nbsp;user$eval1&nbsp;-h<br />
user$eval1&nbsp;-&gt;&nbsp;<span style="color: #0000FF; ">null</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;clojure.lang.DynamicClassLoader@1d25d06e<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;clojure.lang.DynamicClassLoader@1d96f4b5<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;sun.misc.Launcher$ExtClassLoader@69cd2e5f</div>
<br />
&nbsp; &nbsp; 通过-h选项打印了加载user$eval1的类加载器的层次关系，因为user$eval1是动态生成的（clojure启动过程中），因此它不在任何一个class或者jar文件中。除了查询user namespace的类之外，你还可以查询clojure.core,clojure.lang,clojure.java等任何被加载进来的类，例如查询clojure.core.prn的类,在clojure里这是一个函数，在jvm看来这只是一个类：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->housemd&gt;&nbsp;loaded&nbsp;-h&nbsp;core$prn<br />clojure.core$prn&nbsp;-&gt;&nbsp;/Volumes/HDD/Users/apple/clojure/clojure.jar<br />&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;sun.misc.Launcher$ExtClassLoader@69cd2e5f</div>&nbsp; &nbsp;注意，不需要完整的namespace&#8212;&#8212;clojure.core，直接core$prn即可。其他也是类似。<strong>小技巧：如果你实在不知道clojure编译器生成的类名，你可以利用jvm自带的jmap命令来查询。</strong><br /><br />&nbsp; &nbsp;接下来，我们尝试用trace命令跟踪方法的运行，例如例子中的clojure代码用到了loop和recur两个sepcial form，我们跟踪下loop:<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->housemd&gt;&nbsp;trace&nbsp;-t&nbsp;5&nbsp;core$loop<br />INFO&nbsp;:&nbsp;probe&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;clojure.core$loop<br />core$loop.doInvoke(Object,&nbsp;Object,&nbsp;Object,&nbsp;Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br />core$loop.getRequiredArity()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br /><br />core$loop.doInvoke(Object,&nbsp;Object,&nbsp;Object,&nbsp;Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br />core$loop.getRequiredArity()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br /><br />core$loop.doInvoke(Object,&nbsp;Object,&nbsp;Object,&nbsp;Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br />core$loop.getRequiredArity()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br /><br />core$loop.doInvoke(Object,&nbsp;Object,&nbsp;Object,&nbsp;Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br />core$loop.getRequiredArity()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br /><br />core$loop.doInvoke(Object,&nbsp;Object,&nbsp;Object,&nbsp;Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br />core$loop.getRequiredArity()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-ms&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">null</span><br /><br />INFO&nbsp;:&nbsp;Ended&nbsp;by&nbsp;timeout<br />INFO&nbsp;:&nbsp;reset&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;clojure.core$loop</div><br />&nbsp; &nbsp; 在5秒内，clojure.core$loop类有两个方法各被调用了5次，doInvoke是实际的调用，而getRequiredArity用来查询loop所需要的参数个数。trace还可以跟踪到具体的方法，例如我们跟踪prn函数的调用情况：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->housemd&gt;&nbsp;trace&nbsp;-t&nbsp;5&nbsp;core$prn.<strong>doInvoke</strong><br />INFO&nbsp;:&nbsp;probe&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;clojure.core$prn<br />core$prn.doInvoke(Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1ms&nbsp;&nbsp;&nbsp;&nbsp;clojure.core$prn@3e4ac866<br /><br />core$prn.doInvoke(Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;1ms&nbsp;&nbsp;&nbsp;&nbsp;clojure.core$prn@3e4ac866<br /><br />core$prn.doInvoke(Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;1ms&nbsp;&nbsp;&nbsp;&nbsp;clojure.core$prn@3e4ac866<br /><br />core$prn.doInvoke(Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;1ms&nbsp;&nbsp;&nbsp;&nbsp;clojure.core$prn@3e4ac866<br /><br />core$prn.doInvoke(Object)&nbsp;&nbsp;&nbsp;&nbsp;sun.misc.Launcher$AppClassLoader@a6eb38a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;1ms&nbsp;&nbsp;&nbsp;&nbsp;clojure.core$prn@3e4ac866<br /><br />INFO&nbsp;:&nbsp;Ended&nbsp;by&nbsp;timeout<br />INFO&nbsp;:&nbsp;reset&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;clojure.core$prn</div>&nbsp;&nbsp;<br />&nbsp; &nbsp;trace打印了方法的调用次数（5秒内）和每次调用的时间（毫秒级别），以及调用的target object<strong>。小技巧：没有可变参数的函数生成类最终调用的是invoke方法（参数个数可能重载），有可变参数的函数调用的是doInvoke方法。<br /><br /></strong>&nbsp; &nbsp;trace命令还支持打印调用堆栈到文件，例如：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->trace&nbsp;-t&nbsp;5&nbsp;-d&nbsp;-s&nbsp;&nbsp;core$prn.doInvoke</div><br />&nbsp; &nbsp;利用-s和-d命令会将详细的调用信息输出到临时目录，临时目录的路径可以通过trace help命令查询到，在我的机器上是/tmp/trace/&lt;pid&gt;@host目录下。调用堆栈的输出类似：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->example$square.invoke(Long)&nbsp;call&nbsp;by&nbsp;thread&nbsp;[main]<br />&nbsp;&nbsp;&nbsp;&nbsp;example$eval9.invoke(test.clj:11)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.Compiler.eval(Compiler.java:6465)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.Compiler.load(Compiler.java:6902)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.Compiler.loadFile(Compiler.java:6863)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.main$load_script.invoke(main.clj:282)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.main$script_opt.invoke(main.clj:342)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.main$main.doInvoke(main.clj:426)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.RestFn.invoke(RestFn.java:421)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.Var.invoke(Var.java:405)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.AFn.applyToHelper(AFn.java:163)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.Var.applyTo(Var.java:518)<br />&nbsp;&nbsp;&nbsp;&nbsp;clojure.main.main(main.java:37)</div><br />&nbsp; &nbsp;上面这个简单的例子展示了使用housemd跟踪诊断clojure进程的方法。<br /><br />&nbsp; &nbsp;自定义ns和函数的调试与此类似，假设我们有下面的clojure代码：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->(ns&nbsp;example)<br />(defn&nbsp;square&nbsp;[x]<br />&nbsp;&nbsp;(*&nbsp;x&nbsp;x))<br /><br />(loop&nbsp;[x&nbsp;1]<br />&nbsp;&nbsp;(Thread/sleep&nbsp;1000)<br />&nbsp;&nbsp;(square&nbsp;x)<br />&nbsp;&nbsp;(recur&nbsp;(inc&nbsp;x)))</div>&nbsp;<br />&nbsp; &nbsp;ns为example，自定义函数square并定期循环调用。使用housemd诊断这段代码：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->loaded&nbsp;-h&nbsp;example$square&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#查询square的加载情况<br />trace&nbsp;-t&nbsp;10 -d -s example$square.invoke&nbsp;&nbsp;#跟踪10秒内square的调用情况</div><img src ="http://www.blogjava.net/killme2008/aggbug/380822.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2012-06-15 02:52 <a href="http://www.blogjava.net/killme2008/archive/2012/06/15/380822.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Emacs + Clojure配置的几个Tip</title><link>http://www.blogjava.net/killme2008/archive/2012/05/19/378535.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 18 May 2012 16:57:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2012/05/19/378535.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/378535.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2012/05/19/378535.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/378535.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/378535.html</trackback:ping><description><![CDATA[<br />
&nbsp; &nbsp; 很久没更新博客了，在北京工作，忙碌并且充实。目前来说，Clojure最好的开发编辑器应该是Emacs + <a href="http://common-lisp.net/project/slime/doc/html/">Slime</a>的组合，利用<a href="https://github.com/technomancy/swank-clojure">swank-clojure</a>这个项目，加上clojure-mode，可以完美地运行slime。编译、运行、跳转、文档和引用查看甚至<a href="http://georgejahad.com/clojure/swank-cdt.html">debug</a>都可以搞定。具体配置恕不重复，看swank-clojure的文档即可自己安装起来，或者这篇<a href="http://sunng.info/blog/2011/09/beginning-emacs-for-clojure/">中文博客</a>，<a href="http://www.cnblogs.com/darkluck99/archive/2012/02/20/2360216.html">windows上配置</a>。<br />
<br />
&nbsp; &nbsp; 分享几个Tip，也期待大家分享你们的使用心得。<br />
<br />
&nbsp; &nbsp; 首先是自动在打开clj后缀文件的时候启动执行clojure-jack-in与slime连接，可以在emacs配置里加上个callback：<br />
<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->(eval-after-load&nbsp;"clojure-mode"<br />&nbsp;&nbsp;'(progn<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(require&nbsp;'slime)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(require&nbsp;'clojure-mode)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(unless&nbsp;(slime-connected-p)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(save-excursion&nbsp;(clojure-jack-in)))))</div>
&nbsp; &nbsp; 这样在打开clj为后缀的文件的时候，将自动启动clojure-mode执行clojure-jack-in函数并且连接slime。<br /><br />&nbsp; &nbsp; 将clj后缀的文件自动关联到clojure-mode:<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->(setq&nbsp;auto-mode-alist&nbsp;(cons&nbsp;'("\\.clj$"&nbsp;.&nbsp;clojure-mode)&nbsp;auto-mode-alist))</div>
&nbsp; &nbsp; 通常来说如果你是利用<a href="http://marmalade-repo.org/">marmalade</a>安装的，会自动关联的。<br /><br />&nbsp; &nbsp; 另外，启动自动匹配括号、字符串引号等的paredit模式一定要启动：<br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->(defun&nbsp;paredit-mode-enable&nbsp;()&nbsp;(paredit-mode&nbsp;1))<br />(add-hook&nbsp;'clojure-mode-hook&nbsp;'paredit-mode-enable)<br />(add-hook&nbsp;'clojure-test-mode-hook&nbsp;'paredit-mode-enable)</div><br />
&nbsp; &nbsp;在使用clojure-mode或者clojure-test-mode的时候自动启用paredit模式，括号再也不是问题。括号匹配提示一般是开启的，如果没有，强制开启：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->;;&nbsp;&nbsp;&nbsp;&nbsp;显示括号匹配<br />(show-paren-mode&nbsp;t)<br />(setq&nbsp;show-paren-style&nbsp;'parentheses)</div><br />&nbsp; &nbsp; slime更多配置，启用IO重定向（多线程IO输出都定向到SLIME repl）以及设置通讯字符编码等：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->(eval-after-load&nbsp;"slime"<br />&nbsp;&nbsp;'(progn<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(slime-setup&nbsp;'(slime-repl&nbsp;slime-fuzzy))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;(setq&nbsp;slime-truncate-lines&nbsp;t)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(setq&nbsp;&nbsp;swank:*globally-redirect-io*&nbsp;&nbsp;t)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;(setq&nbsp;slime-complete-symbol-function&nbsp;'&nbsp;slime-fuzzy-complete-symbol)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(setq&nbsp;slime-net-coding-system&nbsp;'utf-8-unix)))</div><br />&nbsp; &nbsp; 细心的朋友可能注意到我注释了slime-fuzzy-complete的配置，这是一个支持更好的自动补全功能的SLIME插件（可以用缩写来自动补全），可惜在我机器上没有尝试配置成功，有兴趣你可以尝试下。<br /><br />&nbsp; &nbsp; 在REPL里支持语法高亮，一定要配置上：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->(add-hook&nbsp;'slime-repl-mode-hook<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(defun&nbsp;clojure-mode-slime-font-lock&nbsp;()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(require&nbsp;'clojure-mode)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;(font-lock-mode)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(clojure-mode-font-lock-setup))))</div><br />&nbsp; &nbsp; 单独在clojure-mode（在其他mode里这些快捷键不会起作用）里配置快捷键可以这样:<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->(eval-after-load&nbsp;"clojure-mode"<br />&nbsp;&nbsp;'(progn<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(require&nbsp;'slime)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(require&nbsp;'clojure-mode)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(define-key&nbsp;clojure-mode-map&nbsp;(kbd&nbsp;"M-/")&nbsp;&nbsp;(quote&nbsp;slime-complete-symbol))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(define-key&nbsp;clojure-mode-map&nbsp;(kbd&nbsp;"C-c&nbsp;s")&nbsp;&nbsp;(quote&nbsp;slime-selector)))</div><br />&nbsp; &nbsp;例如我这里将M-/作为自动补全的快捷键，因为meta键在我的Mac机器上设置为command键，因此自动补全的操作习惯就跟Eclipse类似。而<strong>slime-selector</strong>是一个非常有用的函数，用来跳转到slime的一系列buffer，因此我绑定了C-c s快捷键。<br /><br />&nbsp; &nbsp; 额外一提，在Mac osx下，将command作为meta键:<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all">;;;&nbsp;I&nbsp;prefer&nbsp;cmd&nbsp;key&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;meta<br />(setq&nbsp;mac-option-key-is-meta&nbsp;nil<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mac-command-key-is-meta&nbsp;t<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mac-command-modifier&nbsp;'meta<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mac-option-modifier&nbsp;'none)</div><br />&nbsp; &nbsp; 最后，期待大家不吝分享你的心得。<br />&nbsp; &nbsp;&nbsp;<img src ="http://www.blogjava.net/killme2008/aggbug/378535.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2012-05-19 00:57 <a href="http://www.blogjava.net/killme2008/archive/2012/05/19/378535.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java程序员常用工具集</title><link>http://www.blogjava.net/killme2008/archive/2012/04/17/374936.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 17 Apr 2012 09:05:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2012/04/17/374936.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/374936.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2012/04/17/374936.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/374936.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/374936.html</trackback:ping><description><![CDATA[<br />&nbsp; &nbsp; 我发现很多人没办法高效地解决问题的关键原因是不熟悉工具，不熟悉工具也还罢了，甚至还不知道怎么去找工具，这个问题就大条了。我想列下我能想到的一个Java程序员会用到的常用工具。<br />
<br />
一、编码工具<br />
<br />
1.IDE：<a href="http://www.eclipse.org/">Eclipse</a>或者<a href="http://www.jetbrains.com/idea/">IDEA</a>，熟悉尽可能多的快捷键，《<a href="https://www.google.com/#hl=zh-CN&amp;site=&amp;source=hp&amp;q=Eclipse+%E5%B8%B8%E7%94%A8%E5%BF%AB%E6%8D%B7%E9%94%AE&amp;oq=Eclipse+%E5%B8%B8%E7%94%A8%E5%BF%AB%E6%8D%B7%E9%94%AE&amp;aq=f&amp;aqi=g-l1&amp;aql=&amp;gs_l=hp.3..0i13.449l7739l0l7948l53l49l9l4l4l9l278l4511l14j15j7l36l0.&amp;bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&amp;fp=eef1a08d3fa904e4&amp;biw=1594&amp;bih=858">Eclipse常见快捷键列表</a>》<br />
2.插件：&nbsp;<br />
(1) <a href="http://findbugs.sourceforge.net/">Findbugs</a>，在release之前进行一次静态代码检查是必须的<br />
(2) <a href="http://www.atlassian.com/software/clover/overview">Clover</a>，关心你的单元测试覆盖率<br />
(3)&nbsp;<a href="http://checkstyle.sourceforge.net/">Checkstyle</a>&nbsp;代码风格检查<br />
<br />
3.构建和部署工具:<a href="http://ant.apache.org/">ant</a>或者<a href="http://maven.apache.org/">maven</a>，现在主流都是maven了吧，<a href="http://www.sonatype.org/nexus/">使用nexus搭建maven私服</a>，再加上持续集成<a href="http://jenkins-ci.org/">jenkins</a>。代码质量不用愁。<br />
<br />
4.版本管理工具： <a href="http://subversion.tigris.org/">svn</a>或者<a href="http://git-scm.com/">git</a><br />
<br />
5.<a href="http://www.linuxsky.org/doc/admin/200712/213.html">diff和patch</a><br />
<br />
6.设置你的eclipse或者IDEA，如formatter,<a href="http://mestreota.blogspot.jp/2007/11/save-action-on-eclipse.html">save actions</a>以及code template等。代码风格，直接用google的也可以啊。《<a href="http://code.google.com/p/google-styleguide/">Google style guide</a>》<br />
<br />
7.掌握一个文本编辑器，Emacs或者VIM，熟悉常用快捷键。这在你需要在线编辑代码，或者编写其他语言代码时候特别有用。《<a href="http://linuxtoy.org/archives/why-emacs-vim-good.html">神器圣战</a>》<br />
<br />
二、JDK相关<br />
<br />
1.jstat : 观察GC情况，如：<br />
<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->jstat&nbsp;-gcutil&nbsp;pid&nbsp;2000</div>
<br />
2.jmap，查看heap情况，如查看存活对象列表：<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->jmap&nbsp;-histo:live&nbsp;pid&nbsp;|grep&nbsp;com.company&nbsp;|less&nbsp;</div>
<br />
或者dump内存用来分析：<br />
<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->jmap&nbsp;-dump:file=test.bin&nbsp;pid</div>
<br />
3.分析dump的堆文件，可以用jhat:<br />
<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->jhat&nbsp;test.bin</div>
<br />
&nbsp; 分析完成后可以用浏览器查看堆的情况。这个工具的分析结果还比较原始，你还可以用<a href="http://www.eclipse.org/mat/">Eclipse MAT</a>插件进行图形化分析，或者IBM的<a href="https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=4544bafe-c7a2-455f-9d43-eb866ea60091">Heap Analyzer</a>.<br />
<br />
4.jvisualvm和jconsole： JVM自带的性能分析和监控工具，怎么用？<a href="http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/index.html">请自己看文档。</a><br />
<br />
5.jstack：分析线程堆栈，如<br />
<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->jstack&nbsp;pid&nbsp;&gt;&nbsp;thread_dump</div>
<br />
&nbsp; &nbsp; 查看CPU最高的线程在干什么的方法结合top和jstack：<a href="http://www.iteye.com/topic/1114219">http://www.iteye.com/topic/1114219</a><br />
<br />
6.更多JVM工具，参见官方文档：<a href="http://docs.oracle.com/javase/6/docs/technotes/tools/">http://docs.oracle.com/javase/6/docs/technotes/tools/<br />
<br />
</a>7.学习使用btrace分析java运行时问题。《<a href="http://rdc.taobao.com/team/jm/archives/509">Btrace使用简介</a>》<br />
<br />
8.GC日志分析工具：<a href="http://www.tagtraum.com/gcviewer.html">GC viewer</a>、<a href="http://code.google.com/p/gc-console/">GC-console</a>或者<a href="http://stackoverflow.com/questions/1839599/analyze-gc-logs-for-sun-hotspots-jvm-6">自己挑吧。</a><br />
<br />
9.性能分析工具，除了自带的jvisualvm外，还可以用商业的<a href="http://www.ej-technologies.com/products/jprofiler/overview.html">jprofiler</a>。<br />
<br />
<a href="http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm">10.JVM参数大全<br />
<br />
</a>11.《<a href="http://hllvm.group.iteye.com/group/topic/27945">JVM调优标准参数陷阱</a>》，iteye神贴。<br />
<br />
三、Linux工具<br />
<br />
1.<a href="http://www.commandlinefu.com/commands/browse/sort-by-votes">熟悉常用的shell命令，</a><br />
<div style="display: inline-block; "><br />
2.<a href="http://paulkeck.com/ssh/">设置ssh免登陆<br />
</a></div>
<br />
<br />
3.使用<a href="http://htop.sourceforge.net/">htop</a>替换top。<br />
<br />
4.熟悉下<a href="http://www.ibm.com/developerworks/aix/library/au-unix-strace.html">strace,gdb</a>甚至<a href="http://sourceware.org/systemtap/" title="systemtap"></a><a href="http://sourceware.org/systemtap/"></a><a href="http://sourceware.org/systemtap/" title="systemtap">systemta</a>p来分析问题。<br />
<br />
<a href="http://techgurulive.com/2009/01/29/performance-tuning-tools-ps-top-sar-iostat-and-vmstat/">5.熟悉vmstat,iostat,sar等性能统计工具。</a><br />
<br />
5.自动化部署脚本，<a href="http://docs.fabfile.org/en/1.4.1/index.html">py-fabric</a>或者自荐下我的<a href="https://github.com/killme2008/clojure-control">clojure-control</a>。<br />
<br />
四、其他<br />
<br />
1.掌握一门脚本语言，<a href="http://python.org">Python</a>或者<a href="http://www.ruby-lang.org">Ruby</a>，高效解决一些需要quick and dirty的任务：比如读写文件、导入导出数据库、网页爬虫等。注意不是python.com，咔咔。<br />
<br />
2.使用Linux或者Mac os系统作为你的开发环境。<br />
<br />
3.升级你的&#8220;硬件工具&#8221;，双屏大屏显示器、SSD、8G内存甚至更多。<br /><br />4.你懂的：<a href="https://code.google.com/p/goagent/">https://code.google.com/p/goagent/</a><br />
<br />
五、如何查找工具？<br />
<br />
1.搜索引擎，google或者baidu，《<a href="http://www.williamlong.info/archives/728.html">搜索技巧</a>》<br />
<br />
2.万能的stack overflow：<a href="http://stackoverflow.com/">http://stackoverflow.com/<br />
</a>
<br />
3.虚心问牛人。<br /><br />六、最重要的是&#8943;&#8943;<br /><br />一颗永不停止学习的心。<img src ="http://www.blogjava.net/killme2008/aggbug/374936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2012-04-17 17:05 <a href="http://www.blogjava.net/killme2008/archive/2012/04/17/374936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Emacs之一键格式化</title><link>http://www.blogjava.net/killme2008/archive/2011/07/26/355041.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 26 Jul 2011 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2011/07/26/355041.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/355041.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2011/07/26/355041.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/355041.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/355041.html</trackback:ping><description><![CDATA[<br />&nbsp;&nbsp;&nbsp; 格式化源码是很常见的需求，emacs有个indent-region函数用于格式化选定的代码，前提是你处在某个非text mode下，如c-mode或者java-mode之类。如果要格式化整个文件，你需要先选定整个文件(C-x-h)，然后调用indent-region（或者 C-M-\ )。两个命令总是麻烦，我们可以定义个函数搞定这一切，并绑定在一个特定键上，实现一键格式化：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">;;格式化整个文件函数<br />(defun&nbsp;indent</span><span style="color: #000000; ">-</span><span style="color: #000000; ">whole&nbsp;()<br />&nbsp;&nbsp;(interactive)<br />&nbsp;&nbsp;(indent</span><span style="color: #000000; ">-</span><span style="color: #000000; ">region&nbsp;(point</span><span style="color: #000000; ">-</span><span style="color: #000000; ">min)&nbsp;(point</span><span style="color: #000000; ">-</span><span style="color: #000000; ">max))<br />&nbsp;&nbsp;(message&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">format&nbsp;successfully</span><span style="color: #000000; ">"</span><span style="color: #000000; ">))<br />;;绑定到F7键<br />(global</span><span style="color: #000000; ">-</span><span style="color: #000000; ">set</span><span style="color: #000000; ">-</span><span style="color: #000000; ">key&nbsp;[f7]&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">indent-whole)</span></div><br />&nbsp;&nbsp;&nbsp; 将这段代码添加到你的emacs配置文件（~/.emacs)，重启emacs，以后格式化源码都可以用F7一键搞定。<img src ="http://www.blogjava.net/killme2008/aggbug/355041.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2011-07-26 11:24 <a href="http://www.blogjava.net/killme2008/archive/2011/07/26/355041.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>