星期二 四月 21, 2009
Xinfeng Liu
- All
- Java & JES
- MySQL
- 杂谈
- Solaris
- 新闻
如何保护你的原创不被抄袭
SDN China上有不少技术文章被大量转载,有人转载是好事,说明内容有价值。但我以前也看到有些网站转载后不标明原出处和作者,更有甚者,转载时擅自修改内容,断章取义。
最近看到有的本站作者在内容中每隔一段就加上:“转载请注明出处...”的句子。这种方式不会给抄袭者增加太多难度。其实还有其它一些方式:
- 在html里加入一些代码,使内容无法选择和拷贝。此法可骗骗初级人士。
- 在内容中大量使用链接到本站或自己以前文章的链接。这是个不错的办法。
- 还不满意?那么就把内容搞成图片,如果能加上水印就更好了。例如:
Solaris上不是僵尸进程但用kill -9也杀不掉的原因。

仅供参考。
- Xinfeng
Posted at 11:25下午 四月 21, 2009 by xinfeng liu in 杂谈 |
MySQL 5.4 announced, scalability much improved
请注意是Announced,不是released。但现在可以下载preview版本(Solaris或Linux):
http://dev.mysql.com/downloads/mysql/5.4.html
该版本大幅改进了原来MySQL在多CPU系统上的scalability的问题,并在Solaris版本上增加了MySQL的Dtrace probe。
在5.4正式发布时还会增加子查询的优化,存储过程的优化等。
关于scalability的改进,MySQL高级软件架构师Mikael Ronstrom的博客有更多的描述:
MySQL 5.4 Scaling to 16 way x86 and 64-way CMT Servers
更多的性能测试结果细节可参考SUN杰出工程师Allan Packer的博客。
- Xinfeng
Posted at 10:24下午 四月 21, 2009 by xinfeng liu in MySQL |
Adobe Reader 9.1 for solaris x86
其实这东西已经发布半个月了,今天才试了一下,相当不错,中文字体显示得很好。
记得Adobe Reader for solaris x86 的上一个版本是4.05,已经是N年前的古董了。
Download:ftp://ftp.adobe.com/pub/adobe/reader/unix/9.x/9.1/enu/AdbeRdr9.1.0-1_i486solaris_enu.tar.bz2
FontPack (Simplified Chinese): ftp://ftp.adobe.com/pub/adobe/reader/unix/9.x/9.1/misc/FontPack910_chs_i386-solaris.tar.bz2
Posted at 12:24上午 四月 10, 2009 by xinfeng liu in Solaris |
silent data error 和家用openstorage
搞存储的或搞文件系统的人都知道有silent data error的发生,也就是说在整个I/O PATH的某个地方数据出了错,但文件系统并不知晓。我一直没体会到这一点。最近整理照片,发现以前去台北的一些照片坏掉了,MS Windows里并没有报文件错,但这些照片就是无法显示出正常的图像。于是赶紧找移动硬盘的备份,光盘的备份,发现通通都是坏的。坏的文件拷贝得到的结果还是坏的。
这让我想起了ZFS,如果用ZFS早就发现这种错误了,而且即使我只有一块磁盘,我也可以用
zfs set copies=2 <filesystem name> 来提高数据的安全性,ZFS的checksum发现其中一份copy坏掉了,如果另一份copy是好的,它就可以自动恢复。
这又让我想起了一样东西:SUN的openstorage。为什么不做成家用的一个小盒子呢,里面跑ZFS,提供CIFS,NFS服务。利用ZFS提高数据可靠性,并集中管理家中的数据。现在家里的电脑太多了,备份和同步成了头痛事。
其实好多人都有类似的想法了,还有亲自动手干的。我希望SUN也能做些象MAC Mini之类的玩意儿,总比血拼x64服务器要强吧。
Posted at 01:47上午 十二月 11, 2008 by xinfeng liu in Solaris |
JavaFX color lines game
Color Lines游戏是我一家人除我以外都爱玩的游戏。坐在电脑前几个小时只为玩这个游戏太浪费电了,而且腰酸眼花脖子痛。所以我一直在搜集各种版本的Color Lines实现,包括Palm的WinCE的。几年前我一直想用JavaME实现它来装到手机里玩,但一直没兑现自己的承诺。随着JavaFX的正式发布(也就是说API不会再随便改了:) ),我想可以动手干了。当然这个游戏完全没有体现JavaFX的卖点,如果你要体验JavaFX请访问 http://www.javafx.com/ 。
我的游戏实现了Color Lines的基本功能。借此学习一下JavaFX。即使对于我这个几乎从没写过GUI程序的人来说,UI部分的编写也非常简单,因为JavaFX是个描述型的脚本语言,没有用XML来描述界面(我最讨厌XML了,那堆tag明明是给计算机处理的,还说什么human readable,人眼看那些tag不累吗)。而且JavaFX语言里的bind的特性使得UI控制代码和程序逻辑分离得很好。我的这个游戏的源代码量比其它实现要少一些,算上一大堆注释和空行也才600多行。点击PLAY。第一次可能有点慢,不是这个游戏大,编译好后的jar包只有40KB,但是下载需要的JavaFX Runtime比较慢,尤其对于中国用户,去连那个dl.javafx.com太慢了。
JavaFX Mobile还没有发布,想让它运行在移动设备上恐怕要等等了。另外,为了显示效果,程序里用到了一些desktop profile的API。
P.S. 另一位中国同事用JavaFX写的PAC MAN游戏比我这个Cool多了:-)
Posted at 12:55上午 十二月 11, 2008 by xinfeng liu in Java & JES |
使用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 |
使用SUN Studio编译C++程序几个注意问题
不喜欢C++,不规范的C++代码的移植简直就是一场恶梦,即使是在同一种编译器的不同版本间移植也会令人痛苦不堪。Mozilla甚至给出了一个编码规范,以减少跨平台/跨编译器移植的麻烦。不符合该规范的代码一律被认为BUG,即使代码的功能正确。
不同编译器编出来的C++代码通常是不能混用的。因为C++有个符号mangling的问题,不同的编译器有不同的mangling方法,导致符号不通用。Solaris上的Java虚拟机是用Sun compiler编译的,因此如果你有JNI代码是C++写的,你应该用Sun compiler编译JNI代码。(当然Sun compiler是免费的)。编译各种操作系统平台的JNI代码的建议编译选项见Kelly O'Hair的blog。
Sun compiler编译可执行程序时会自动链接 -lCstd -lCrun -lm -lc ,但编共享库时却不会。所以编共享库时应该显式地加上这些链接选项。
Sun compiler 也同时提供标准C++库的stlport实现,编译时可以加上-library=stlport4以使用stlport的实现而不是自带的libCstd.so.1。但这二者在同一程序中不能混用。
如果用DTrace来调试C++程序,函数名要使用mangle过的符号,因为DTrace不认识C++(mdb也是这样)。想得到mangle过的符号可以通过nm -C <binary name> 得到。如果要跟踪函数的参数,第一个参数通常应该是arg1而不是arg0,因为C++中类成员函数映射成C代码后第一个参数一般都是this指针。比如下面的DTrace脚本跟踪某个函数的调用过程:
#!/usr/sbin/dtrace -qFs
pid$target::__xxxxxx_:entry
{
self->traced=1;
printf("thread #%d is doing %s \n", tid, copyinstr(arg1)); /* suppose arg1 type is char* */
}
pid$target::__xxxxxx_:return
{
self->traced=0;
}
pid$target:::entry
/self->traced/
{
printf("thread #%d is calling %s .\n", tid, probefunc);
}
pid$target:::return
/self->traced/
{
printf("thread #%d returns from %s .\n", tid, probefunc);
}
Posted at 12:52上午 九月 12, 2008 by xinfeng liu in Solaris |
