分类 Java 下的文章

启动jvm虚拟机时的“段错误”

今天,在部署U盘程序时,重启resin时,报错


#

# An unexpected error has been detected by HotSpot Virtual Machine:

#

# SIGBUS (0x7) at pc=0x00000034da87aa5b, pid=3236, tid=47594056421008

#

# Java VM: Java HotSpot(TM) 64-Bit Server VM (1.5.0_19-b02 mixed mode)

# Problematic frame:

# 段错误


此时,无论直接运行java或用ant编译,都报以上错误


把所有的java进程都kill掉后,可以正常重启2个jvm,在启动第3个时,同样的错误又出现了


尝试更换成jdk5的其它版本,错误依旧


于是,决定用jdk6试试,如果不行,准备只好重启机器了...


没想到,在安装jdk6时,失败了,先提示/tmp空间不足,然后又报段错误


这时,才突然明白,可能是/tmp空间满了,导致无法运行java


把/tmp空间清理后,用以前的jdk可正常启动resin了


那么,启动java进程时,会向/tmp目录下写什么东西呢?


进去后,会发现有一个/tmp/hsperfdata_root目录


该目录下有一些文件,这些文件就是对应java进程的pid


而文件的内容似乎是启动java的命令,还有其它的一些log信息


看来java是利用该文件来记录启动时的一些log了


郁闷的问题,下午折腾了好久......


 

C#中ShowBalloonTip气泡不显示的问题

最近,使用C#开发一个windows上的客户端


使用了系统托盘控件notifyIcon,并有一个气泡通知的方法:



折叠复制代码




  1. protected void nofityMsg(string title, string msg)  

  2. {  

  3.     this.notifyIcon1.BalloonTipTitle = title;  

  4.     this.notifyIcon1.BalloonTipText = msg;  

  5.     this.notifyIcon1.Visible = true;


  6.     this.notifyIcon1.ShowBalloonTip(Notes.SYSTRAY_NOTIFY_TIME);  

  7. }







但运行后,托盘的气泡死活不能出来


后来才知道,windows的注册表里有一个键值,可以控制是否禁用托盘气泡提示


原文见:http://support.microsoft.com/kb/307729


修改注册表以下键值为1即可:


HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerAdvancedEnableBalloonTips

使用Java java_memcached client的陷阱

这2天,才发现之前我们的某个开发人员使用java_memcached-release_2.0.1.jar是有问题的


在我们的某个模块里,需要2个memcached,分别提供不同的服务


于是,开发的人员就从网上粘贴来如下的码,分别生成2个MemcacheUtil类



折叠复制代码




  1. static {   

  2.     mcc = new MemCachedClient();   

  3.     SockIOPool pool = SockIOPool.getInstance();   

  4.     String[] servers = { "192.168.1.1:11122" };   

  5.     pool.setServers(servers);   

  6.     pool.setInitConn(5);   

  7.     pool.setMinConn(5);   

  8.     pool.setMaxConn(20);   

  9.     pool.setMaxIdle(1000 * 60 * 60 * 6);   

  10.     pool.setMaintSleep(30);   

  11.     pool.setNagle(false);   

  12.     pool.setSocketTO(3000);   

  13.     pool.setSocketConnectTO(0);   

  14.     pool.initialize();   

  15.   

  16.     mcc.setCompressEnable(true);   

  17.     mcc.setCompressThreshold(64 * 1024);   

  18. }  






在2个类里,分别初始化2个不同的mcc,这样做其实是有很大问题的


因为,在初始化MemCachedClient和SockIOPool时,均没有指定对应的name


这样,memcached client会默认生成一个name为default的pool


也就是说,即使你初始化了2个不同server对应的mcc,但实际上只有一个default的pool


这个pool里对应的memcache server完全取决于这2个类的初始化顺序


最后初始化的class,会覆盖掉第一次所用的server


因此,用这样的方式,实际上最后使用的还是其中的某一个memcache server


造成memcache中的数据全部乱掉


正确的方法应该是



折叠复制代码




  1. SockIOPool pool = SockIOPool.getInstance(poolName);   

  2. ....   

  3. MemCachedClient mcc = new MemCachedClient(poolName);  






初始化时,需要指定唯一的一个poolname,这样就能避免刚才的问题了


另外一个问题就是,用python或其它方式写入memcache中的数据,使用java client无法获取到


再查看了memcache client的源码后,发现了以下2点:


1. 它会默认对要存储的key进行URLEncoder的编码,如会把@给编码成%40


2. 在get调用时,如果没有传递参数asString,则它默认会对取到的value进行它自己的decode


所以,如果要想client能正确的取到没有编码过的数据,则需要



折叠复制代码




  1. //设置不对key做编码   

  2. mcc.setSanitizeKeys(false);   

  3. //最后一个参数true,表明get时直接返回String,而不进行解码   

  4. mcc.get("aaaaaaa@sohu.com",null,true);  




scrip:0112t>

使用Jprofiler来监控jvm的运行

最近几天,线上的积分服务器不停的报警重启


看了resin的log信息,既没有OutofMemory,也没有其它的异常


偶尔有几个“Too many open files”的异常


通过ulimit -a查看最大打开文件数,发现是1024,于是执行


ulimit -SHn 65536


调大打开文件数目,但还是没有作用,用lsof -p来查看对应的进程


有1000多个打开的文件,而且有很多sock文件,一直处于ESTAB状态,似乎没有释放


于是,开始怀疑是程序的某个地方有问题,造成resin的Thread堵塞


由于从resin的log里无法定位到具体的位置,所以就想到了用Jprofiler来调试


在Jprofiler里建立一个remote application后,就能监控服务器上resin的各种状态了


可以查看内存状态,cpu状态,线程状态,虚拟机的状态等


由于我怀疑是线程堵塞,所以就直接到Thread Views里查看线程情况


使用Thread Dump,Dump出某个时刻的所有线程


看到有很多如下的Thread:



折叠复制代码




  1. Thread resin-tcp-connection-127.0.0.1:6837-373:   

  2.   at sun.misc.Unsafe.park(boolean, long)  

  3.   at java.util.concurrent.locks.LockSupport.park()  

  4.   at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt()  

  5.   at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(int)  

  6.   at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(int)  

  7.   at java.util.concurrent.Semaphore.acquire()  

  8.   at com.sohu.score.common.SubScoreSocketPool.subScore(java.lang.String, int)  






很明显,是方法subScore出问题了,造成一堆的Thread堵在那个地方,不释放资源,把resin给堵死了


然后,在对应的方法里加上debug log,最终很快就找出了错误所在


原来的程序使用了信号量semaphore来获取连接,对于socket结果正常,会release对应的信号量


但当socket返回错误信息时,程序没有release对应的semaphore就直接return了,导致semaphore很快被用完了


很多thread堵塞在了Semaphore.acquire() 地方


修改了程序后,Resin就运行正常了...


对于程序中的内存泄露,使用Jprofiler也能很容易的查出来


只要我们把某个时刻的heap给dump出来,就能很快看出占用内存过大的方法


内存泄露基本上就是对应的方法造成的

Jprofiler的安装配置

JProfiler 是一个用于 java 系统监控分析的软件,功能很强大


它可以监控普通的 java application, application server 等


除了可以监控本地的程序,还可以对远程服务器上跑的应用进行监控


如果需要对远程服务器上的webserver进行监控,需要下载windows版本和linux版本



  1. 下载jprofiler_windows_6_0_3.zip,解压后,直接运行bin/jprofiler.exe即可开始安装

  2. 下载jprofiler_linux_6_0_3.sh,执行:


  3. 折叠复制代码




    1. chmod a+x jprofiler_linux_6_0_3.sh

    2. ./jprofiler_linux_6_0_3.sh

    3. vi /etc/profile

    4. export LD_LIBRARY_PATH=/opt/jprofiler6/bin/linux-x86:$LD_LIBRARY_PATH





  4. 在webserver中配置jprofiler,加入以下内容:对于Resin2.x和Resin3.0,将以上内容配置在resin/bin/wrapper.pl中的$JAVA_ARGS中,对于Resin3.1.x,则配置在resin.conf中 的<jvm-arg>中即可



折叠复制代码




  1. -agentpath:/opt/jprofiler6/bin/linux-x86/libjprofilerti.so=port=8849




       4. 在windows上启动jprofiler,新建一个remote application session,一步一步的走下去


注意:如果新建session的时候,采用的是默认的wait for a conectin from the JProfiler GUI,那么在resin 里配置好Jprofiler后,resin的进程并不会马上启动,只有当Jprofiler的客户端连接上8849端口后,resin才会真正的启动


 

Ant增量编译的陷阱

之前,曾经写过通过rsync和ant来部署java代码,见:www.tech126.com/?p=88/


但却忽略了一个问题,当服务器的时间不准确时,那么rsync过去后,可能会对ant编译的结果造成影响


因为,ant缺省是增量编译的:


The source and destination directory will be recursively scanned for Java source files to compile. Only Java files that have no corresponding .class file or where the class file is older than the .java file will be compiled.


就是说,只有build目录下没有对应的class文件,或者class文件的时间比src的时间old时,才会编译对应的java文件


如果我们部署时,服务器的时间不准确,比当前时间晚上一定的时间,比如一个小时,或一天


那么有可能,我们本次修改的java文件就没有被rsync到对应的服务器上,或者即使rsync过去了,但仍然没有被ant编译


可能就会造成明明修改了java文件,但部署后在对应的服务器上却没有体现修改的内容


上午,在passport部署时,就出现了这个郁闷的问题,后来仔细分析了一下,发现正是41.239的服务器时间不正确导致的


所以,最好在服务器上加一个ntpdate的cron,来定期同步服务器的时间,保证其正确性

Java中获取文件路径的分隔符

如果一个应用既要运行在Windows系统上
又可能会运行在Linux系统上
那么如何定义一个通用的文件路径分隔符呢
可以通过下面方法来获取
System.getProperty("file.file.separator")

其实,Java的System类提供了很多的系统属性
如:操作系统名字,版本,虚拟机的名字.....
可以通过
System.getProperties().keySet()
来取得系统所有的属性列表



Hibernate实体对象继承的映射

标签:hibernate 

     如果实体之间存在继承关系,如User和Student,Teacher,那么对应到数据库表的hibernate映射有3种方式:

     1.每个具体类一个表:如上例子,就对应3张表,3个表之间是独立的。可以使用<union-subclass>来映射其关系,还可以直接写3个独立的<class>来映射。用<union-subclass>进行映射,会减小配置文件的大小,但必须要求三个实体的公共属性在数据库中字段名要一致。

    2.所有具有继承关系的实体一张表。可以使用<subclass>来进行映射,Chlid表只需要映射自己独立的字段就行了,但在数据库中会有冗余的字段,Student和Teacher实体自己的属性都需要在一张表中,而且表中还需要有一个字段来标识该记录是哪个实体的。

    3.每个子类一个表。可以使用<joined-subclass>来进行映射,User表只存公共的字段,而Student和Teacher表分别存自己的字段,但他们各有一个外键和User表相关联。

    比较这3种方式,第3种实现应该是最合理的,它的配置相对比较少,而且数据库表结构和字段均没有冗余,但其实现查询是稍微麻烦一些,需要左连接,insert和update时均需要修改2张表的内容。

 

关于js和后台的jsp中文转码的一点经验

标签:javascript  java  中文问题 

最近做的一个项目中,需要前台用js来请求一个jsp文件,其中传递的参数中可能含有中文,还有特殊字符,所以需要在js中首先进行一下转码:

encodeURIComponent(str)

这样,该参数就被默认编码为UTF-8格式了,在后台的jsp中为了能得到相应的中文,需要首先将request的编码设置为UTF-8:

request.setCharacterEncoding("UTF-8");

然后,再得到参数值:

request.getParameter("userid");

正常情况下,如果你的环境默认编码为GBK的话,就能得到正确的中文了。

但如果你的环境默认为英文的话,则还需要进行以下转码:

new String(str.getBytes("GBK"));

JAVA验证字符串转换为日期的合法性

标签:nbsp 

       String  text  ="1996-11-3 13:23:23";
       Date  d  =  null; 
       SimpleDateFormat  df  =  new  SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
       df.setLenient(false);//这个的功能是不把1996-13-3 转换为1997-1-3
        try
       { 
         d  =  df.parse(text); 
       }
       catch(Exception  e)
       { 
         d=new  Date();
         System.out.println("你输入的日期不合法,请重新输入"); 
       } 
       String sdata=df.format(d);
       System.out.println(sdata);

最新文章

最近回复

  • feifei435:这两个URI实际是不一样的
  • zsy: git push origin 分支 -f 给力!
  • 冼敏兵:简单易懂,good fit
  • Jack:无需改配置文件,看着累! # gluster volume se...
  • Mr.j:按照你的方法凑效了,折腾死了。。。。
  • zheyemaster:补充一句:我的网站路径:D:\wamp\www ~~菜鸟站长, ...
  • zheyemaster:wamp2.5(apache2.4.9)下局域网访问403错误的...
  • Git中pull对比fetch和merge | 炼似春秋:[…] 首先,我搜索了git pull和git fe...
  • higkoo:总结一下吧, 性能调优示例: gluster volume s...
  • knowaeap:请问一下博主,你维护的openyoudao支持opensuse吗

分类

归档

其它