人生的必经之路

2012年1月11日 hashei 2 条评论

今天看了《那些年,我们一起追女孩》,趁着“余音绕梁”,记录一下观后感。

故事梗概不用再复述,剧情其实很简单,就是九把刀的个人自传,但是一个自传能引起观众的共鸣并叫好——至少我是——是因为他拍出了那些年,我们都曾有过的青春岁月。

开头的一段,柯景腾被安排坐在沈佳宜前接受“帮教”,这个情节大陆学生也都经历过。不过因为初中阶段我还算一个好学生,属于被老师安排帮教别人的那部分,所以这一段倒也没有什么大的感触。最初产生共鸣的,是沈佳宜扎了马尾辫走过操场,五个男生都觉得沈佳宜对自己有意思的感叹这一情节。虽然有故意制造喜剧的因素在内,但耳边却响起了这么一段歌词“为什么我总觉得你好像其实在注视着我”,明明自己喜欢别人,却觉得别人的一言一行其实是为你做的,这事儿,有过经历的人怕不难体会。之后接着黄舒骏的一首《恋爱症候群》听的人不由会心一笑。

  • 一般发病後的初期反应会开始改变一些生活习性
  • 洗澡洗得特别乾净 刷牙刷得特别用力 半夜突然爬起来弹钢琴
  • 有人每天站在阳台对路人傻笑 有人突然疯疯癫癫 突然很安静
  • 有人一脸痴呆 对着镜子咬着指甲打喷嚏 有人对着小狗骂三字经
  • 女人突然改变发型 男人开始每天练着哑铃
  • 食欲不振歇斯底里四肢萎缩神经过敏发抖抽筋都出现在这时期
  • 如果在这里结束,两人走在一起的话就是童话般美好的故事了,不过这是一篇自传,就注定不会那么一帆风顺。表白未遂的那一段,我觉得很真实。男生平时大大咧咧,脑袋大条一点多的是,可是在喜欢的人面前总是会很敏感“爱一个人常常很小心,仿佛手中捧着水晶”。所以沈佳宜说出“其实我没你想的那么好,也许你只是喜欢想象的我,你好好想想到底喜不喜欢我,都没有好好考虑就回答”的时候,柯景腾疑惑了,“明明站在你的面前,还是害怕这是一场梦”。在戏外的我们心里都在说好傻,这连考验都算不上,就是个试探,抑或说是欲迎还拒。可是那时候的男生哪知道这时要跟上“我喜欢的不是完美的你,而是在家邋遢、有起床气的真实的你”。

    因为彼此都是第一次,所以他们的感情在第一次遇到矛盾的时候就断了,不是心灰意冷的破灭,而是硬生生的断开了。沈佳宜在雨里哭骂大笨蛋的时候,你我都知道“大笨蛋”指的什么,但是自尊心受到打击的柯景腾那时以为的是比幼稚更重的伤害。第一次恋爱是单纯的,所以过于脆弱,没有经历住风雨。沈佳宜和阿和在奶茶店,看到一对闹矛盾的情侣最终拥抱在一起的时候,脸上露出的笑容有羡慕,也有祝福。而柯景腾当然也不会忘了沈佳宜,所以台湾921大地震,第一个想到的就是打给她,当然这时候两人之间更多的是友谊。

    婚礼上,柯景腾心里说出“看到喜欢的女生有人疼爱,心里会是真正的祝福”,故事在这里结束那也算是一个happy ending。可惜导演要把最残酷的一面放给你们看,“如果柯景腾向我表白,我会很高兴的”,“好,在一起”。这两句话不知道看得多少男生会肝肠寸断,心痛不已。所以在平行的另一个世界中,柯景腾蹲在沈佳宜面前,向她道歉“对不起,是我太幼稚了”,地震的时候沈佳宜也在焦急的搜索信号,婚礼上深情相拥的是他们俩,可惜现实不是。

    历史是由一连串的偶然事件组成,这些偶然最后形成一个结果,像蝴蝶扇动的翅膀,这些无法确定的因素共同导致一个结果。无所谓对错,发生了的都叫做必然。而过程当中,任何一项的改变,都可能形成别样的结局。所以初恋失败的人不必痛苦,因为获得了人生中最纯真的经历。而再次投入感情的男女也不用怀疑对方的体贴,动听的话是不是锻炼出来的花言巧语,这是在体会了失去的痛苦后,为了不失去现在的你而做出的改变。联想起前几天看的《失恋33天》,黄小仙说她知道了,她的任性,嘴如尖刀不饶人破坏了陆涛心中的美好形象,以后再也不会了。这种改变应该就是恋爱所得到的经验吧。

    最后从我个人的角度说一下柯景腾那场格斗比赛的意义。从进化心理学的角度分析,一场战斗,是男性的本能,竞争、追求层级。好莱坞的电影中,有多少是关于拳击的?《愤怒的公牛》、《洛奇》、《搏击俱乐部》,女生也许对这项运动无感,但男生肯定是热血沸腾的。从文艺的角度分析,这场战斗是柯景腾实现自己从小的梦想,在心爱的人面前把纸上的李小龙真真切切付诸现实,是一场宣告男孩进化成男人的仪式。所以他说这是对于他十分重要的东西,不过可惜的是仅仅对于他而言。

    分类: 生活感想 标签: ,

    tuxedo11g MP 模式配置

    2011年12月4日 hashei 2 条评论

    随着一些项目对实时交易处理量和响应时间的要求较高,最近两月接触了交易中间件的安装配置。上一会写了CICS的相关内容,这次整理一下oracle tuxedo的内容。tuxedo 11g在系统架构和基础配置文件上和之前的版本没什么区别。下文内容为整理而得,较中文网络其它的文章,多了多域间网关对的配置,这一点在MP模式下还是较为有用的。

    Tuxedo架构图

    tuxedo架构图

    说明:域(DOMAIN)

    域是具有相同功能或结构的应用系统的集合。应用系统可以有多台服务器组成。Tuxedo的域特性把客户/服务器模型扩展到多个独立自治的应用系统。一个域既可以是一组Tuxedo的应用程序,也可以是一组运行在另一个非Tuxedo环境中的应用程序。Tuxedo的每个域独立完成域内的操作,域间操作由域网关完成。

    比较重要的进程为

    1、BBL(Bulletin Board Liaison),主要对公告板等进行管理,包含了一个公告牌的本地拷贝和本地服务器上应用的状态。

    Bulletin Board(BB,公告板):Tuxedo把系统的配置信息保存在一个共享内存中,该共享内存称为公告板。

    2、DBBL(Distinguished Bulletin Board Liaison),TUXEDO用于多服务器配置各个服务器之间的协调工作,只有当TUXEDO配置为MP方式时才需要用到DBBL。DBBL与BBL协同,保证所有的公告牌内容的一致性。

    3、WSL:WorkStation Listener,Tuxedo系统自带的一个Server,它侦听一个指定的端口,WSC最初与该Server建立连接。

    4、WSH:WorkStation Handler Server ,Tuxedo系统自带的一个Server,由它处理WSC与Tuxedo Server之间的通信。

    5、BRIDGE,不同的服务器之间通过BRIDGE进程进行通讯,该BRIDGE的侦听IP地址及端口 在NADDR中指定。如果是在UNIX下要指定该BRIDGE所用的网络设备,如果是在NT下则不要。

    6、DMADM,域间通信的进程:管理域的server,在运行时管理BDMCONFIG,对已登记的gateway group提供支持,在tuxedo系统中,只能有一个DMADM进程,且不能对它采用MSSQ,不能有REPLYQ

    7、GWADM,管理DOMAIN的域网关进程(在/DOMAIN中是GWTDOMAIN)的SERVER,在运行时可以对某一组域网关(Domain Gateway Group)进行管理。主要从DMADM那里取得域的配置信息,并对域网管进程及跨越域的全局事务的LOG文件进行管理

    8、GWTDOMAIN,处理DOMAIN之间的互操作,使本地域和调用远程域可以互相调用彼此的service,其中GMADM和GWTDOMAIN必须在一个组中,一个tuxedo应用可以有多个GWADM,GWTDOMAIN对,一个组只能有一个GMADM,GWTDOMAIN对,但一个tuxedo应用只能有一个DMADM, DMADM可以在任何一个组中,一个本地域可以和多个远程域实现互操作。

    9、tlisten,是TUXEDO自带的管理程序,在MP模式下,完成主机之间的初始化通讯,如非MASTER机从MASTER机中下载tuxconfig配置文件。

    tlisten的启动办法:tlisten –l //NLSADDR

    以上几点概念清楚后,就可以尝试配置一个简单的tuxedo环境了。

    阅读全文…

    分类: tuxedo 标签:

    理智与情感(一)

    2011年11月14日 hashei 2 条评论

    这个月更新的文章还不少,不过第一篇是10年,这两篇是11年,希望下一篇不要是在方舟上更新的。

    我标题写《理智与情感》,当然不是要向Jane Austen叫板,而是最近几年的人生经历让我感悟到:我们人生所有的烦恼乃至痛苦,都来自于一种矛盾——在需要理智的时候感性,而在需要情感的时候却理性过度。

    首先澄清一点,本人85年生,写人生感悟并不是因为老气横秋,而是因为直到暮年才有自己的心得或许对得起子孙,却断然对不住自己。而他人只能给一些客套的赞美与廉价的鼓励,与大多数困难障碍相比,它们都更加凶险。所以我要在年轻的时候给自己定一个准则,哪怕选了一条充满荆棘的路,也好过原地兜圈子。

    在做一些影响久远的决策前,我们总是显得轻率。我在之前的一篇博客里提到过,我们选择专业、选择职业,很大程度上受当时社会潮流的影响,为了“从这5年后,当你看到你的朋友买车买房时不会诅咒自己。”。可是拉长到几十年来看,一时的潮流犹如昙花一现。上世纪六七十年代工人最光荣,哪想九十年代成了需要哪里跌倒哪里站起的一批人。八十年代改革春风带起的个体户、乡镇经济,九十年代在港商台商和私营经济的冲击之下,每况愈下,纷纷破产。而那时风光的私营企业,如今不得不面对日益沉重的税收和垄断国企的咄咄逼进。现在毕业生挤破头都想进去的公务员,我小时候看的《故事会》里,总要面对工资打白条的窘境。如果说之前的时代是因为缺乏选择,所以一辈人不得不荣辱与共,那么现在这个选择多元化的日子里,选择一个适合自己的工作就很必要了。而这个需要理智思考的过程,却退位让给了感性选择。

    当今年轻人,除了工作,关心的话题之一必然有房产。无房不成家也好,有房只不过是七十年的租期也罢,你不想关心这个话题,父母、朋友、新闻会把你硬拽进来,最近因为房价下跌而砸开发商售楼部的报道可谓一场悲喜剧。不过这个问题,经历过大风大浪的美国人早就总结给你了——房产买好了是资产,买遭了是负债。就近的香港市场来说,也已历经三次大起大落。所以除非你富二代,除非你是颜回能居陋巷而不改其乐,用房产让自己财富增长是个跨越不过去的难题。可是有多少姻缘因为房产的原因而拆散,又有多少夫妻在坚硬的钢筋水泥的城市里扎不下根来?这是理性让位感性的第二个例子。

    第三个例子,是父母一辈时常叮嘱的“莫谈国事”,可是梁漱溟老生前曾说“中国人是公事没人管,私事人人都来管。只有不知自己自由的人,才会不知道尊重别人的自由;只有不知自己的自由也不知别人自由的人,才会完全冷漠于公干,热衷于私涉。大多数人都懂得并珍视自己的自由时,一个社会才会有宪政制度,有民主政治,有自由与共和精神。”现在网上种种恶性事件,你不去关心,将来总会落到你身边,丧钟是为你我而鸣。但是如何关心又是个大问题,是像《乌合之众》里描写的大众的非理性幻想和群众性癫狂那样,还是独立于大众之外,基于批判性思维来理解和分析?“思想因浅薄而确定,确定导致了专制;思想因深刻而怀疑,怀疑导致了民主”,可惜我也时常因为冲动而放弃了怀疑精神,以致事后看来像个大傻瓜。

    说到冲动,那我时常又嫌自己做的不够,总是差一点不反顾的勇气,让我始终做不成想做的那个自己。面对生活和感情,总是用过于理智的声音来为自己的不作为而开脱。诚然感情不是一帆风顺的,但是担心未曾发生的事不得不令人怀疑是性格悲观还是缺乏自信了。这是感性让位理性的例子。

    如上种种的左右大脑错位,导致了生活中的迷茫、困惑,又进而衍生出了不安全感。所谓不安全感,在我看来就是缺乏确定性。我们在一个陌生的地点,不知道这是哪里、举目无亲、不知道怎么回到自己熟悉的地方,会十分害怕。同理在人生的道路上,不知道过去的日子是怎么过去的,不知道现在在做什么,不清楚将来会怎么样,就产生了极大的不安全感。

    以上唠叨了那么多是为什么要写《理智与情感》,对这些问题的解答其实很简单,要找到自己的准则,也就是形成自己的人生观、价值观。你肯定想这不是说了等于没说么?我们成长过程中确实是会灌很多心灵鸡汤,学校、家庭也灌输了很多,但是这些都没有经过自己的思考,有些还是互相矛盾的,有些知道不错但做起来十分痛苦。所以唯有坦然的面对自己,和心灵对话,找到适合自己的,逻辑自洽的三观。

    这个话题会是一个长篇,接下来几篇会详细写写我总结的思考。这篇的最后附上雨果的一段话,也是我所希望达到的境界:生活,就是理解。生活,就是面对现实微笑,就是越过障碍注视将来。生活,就是自身有一架天平,在那上面衡量善恶。生活,就是有正义感,有真理,有理智,就是忠矢不渝、诚实不欺、表里如一、心智纯正、并对权利义务同等重视。生活,就是知道自己的价值、自己所能做到的与自己应该做到的。

    分类: 生活感想 标签:

    CICS7.1安装与配置步骤

    2011年11月13日 hashei 1 条评论

    今年国庆扬州之行在AIX6上安装CICS7.1,耗费一周精力仍旧错误百出,最后依靠这篇步骤完成成功。贴出来让有需要的人也少走弯路吧

    1. 安装环境

    主机:

    操作系统:AIX6100-06-01-1043,使用异步IO(无需设定,系统自动)

    数据库:Oracle11.2.0.2(单机版本),安装constant client 32bit(复制为lib32目录)

    编译器:XLC10.1

    2. 创建cics、cicsterm和cicssm组,创建cics用户和cicssm用户添加至cics(primary group)、cicsterm和cicssm组,采用本地认证,Soft FILE size核soft CORE file size的参数值设置-1(unlimited)。

    3. 如果数据库是Oracle10.2.0.1,则执行这个步骤:将root用户和cics用户添加到dba组。Oracle10.2.0.1安装完成后安装目录下的子目录的属性大都为750,库文件属性为640,导致cics用户无法访问Oracle的库文件。并且这些目录文件的属性和用户的umask设置没有关系。

    4. 创建/var/cics_servers、/var/cics_regions文件系统并且mount,修改属性为cics:cics。

    5. 将root添加至cics与cicsterm组并且是组的管理员,并将环境变量加入其profile文件(程序安装时自动添加到/etc/profile文件)。

    export LANG=en_US

    export PATH=$PATH:/usr/lpp/cics/bin:/usr/lpp/cicssm/bin

    export LIBPATH=$LIBPATH:/usr/lpp/cics/lib:/usr/lpp/cicssm/lib

    export NLSPATH=/usr/lpp/cics/msg/%L/%N:/usr/lpp/cics/msg/C/%N:/usr/lpp/cicssm/msg/en_US/%N:/usr/lib/nls/msg/%L/%N

    6. 安装gsk(在CICS光盘的/gskit/gskta.rte)

    7. 安装CICS,执行./TXSeriesV71-AIX.bin -i console

    ü 选择安装时的语言环境

    ü “产品简介”

    ü 如果已经安装了6.X版本,确认升级到7.1版本

    ü 接受软件协议,开始安装。确认/usr文件系统有足够的空间

    ü 安装完成后可以选择察看“安装选择摘要”,确认安装

    ü 安装完成后,可以选择察看readme文件以及安装日志(install_location/logs)。如果安装失败,在/tmp中创建日志文件

    ü 不创建缺省的CICS region以及SFS server

    8. 安装CICS7.1.0.2升级补丁,方法和安装CICS7.1类似。

    9. 创建SFS_SERV用户,并添加至cics、cicsterm和cicssm组。这个用户名称是系统保留的SFS服务器的short name,SFS服务器根据short name名称定位使用的SFS存储。

    10. 创建sfs_SFS_SERV与log_SFS_SERV逻辑卷(注:SFS服务器数据卷与日志卷名的格式为sfs_sfsUserName、log_ sfsUserName,其中sfsUserName为前面步骤创建的用户名),并输入chown SFS_SERV:cics /dev/*sfs_SFS_SERV /dev/*log_SFS_SERV命令更改其属主。sfs_sfsUserName和log_ sfsUserName大小为1G。

    11. 输入/usr/lpp/cics/bin/cicsdefaultservers命令自动创建缺省的SFS服务器资源定义文件。

    12. 输入cicssfscreate -v /.:/cics/sfs/sfsServerName,并将前面步骤创建的SFS_SERV用户的Home目录更改为/var/cics_servers/SSD/cics/sfs/sfsServerName,其中sfsServerName为本步中所创建的SFS服务器名。

    13. 输入/usr/lpp/cics/bin/cicssfs –v /.:/cics/sfs/sfsServerName StartType=cold命令冷启动SFS Server,并输入/usr/lpp/cics/bin/sfsadmin list lvols -server /.:/cics/sfs/sfsServerName命令来验证SFS Server是否已正确启动。如果SFS Server正常运行,那么命令输出将显示为SFS创建的数据卷的名称。如果要重建SFS Server,先停止原来的服务再删除。冷启动SFS会消除在SFS数据逻辑卷上的文件。

    14. 通过cicsdefault -r cicsRegionName命令创建CICS Region。如果是重建的话,首先通过ps –ef | grep cics找到所有的遗留进程,杀死这些遗留进程后再执行。

    15. 输入/usr/lpp/cics/bin/cicsupdate -c rd -r cicsRegionName DefaultFileServer=/.:/cics/sfs/sfsServerName命令,将CICS Region的 DefaultFileServer 属性更改为 SFS Server的全限定名。

    16. 输入cicsadd –c ld –r cicsRegionName LDName TCPService=’serviceNa命令添加配置一个新的LD,并在/etc/services文件中增加相应servieName的设置,只要增加TCP端口,缺省为1435。

    17. 创建Switch Load File,配置XAD,连接数据库。

    ü 保证已安装支持版本的C编译器

    ü 保证已安装Oracle客户端与proc编译器

    ü 保证操作系统中已设置ORACLE_HOME(对应于本地客户端软件)环境变量的值,并已完成TNS的配置,可通过sqlplus连接至Oracle数据库;

    ü 将/usr/lpp/cics/examples/RM_support/Oracle下的oracle1pc.pc与oracle1pc.mk文件复制至/var/cics_regions/cicsRegionName/bin目录下;

    ü 在该目录下根据Oracle版本通过make –f oracle1pc.mk oracleversion命令生成和数据库的链接程序(Swith Load File)——oracle1pc。

    ü 输入cicsadd –c xad –r cicsRegionName XADName SwitchLoadFile=’fileName’ XAOpen=’Oracle_XA+Acc=P/oracleUserName/oracleUserPassword+SqlNet=oracleTNSName+SesTm=35+LogDir=/tmp+DbgFl=1’命令添加配置一个新的XAD。

    ü 赋予用户权限,grant select on dba_pending_transactions to oracleUserName;

    18. 在/var/cics_regions/cicsRegionName/environment文件中,根据数据库的配置情况设置ORACLE_SID(对应于目标数据库)、ORACLE_HOME(对应于本地客户端软件)、NLS_LANG环境变量的值,也可以设置CICS_XP_RECV_TIMEOUT的值。

    19. 通过/usr/lpp/cics/bin/cicscp –v start region cicsRegionName StartType=cold命令冷启动Region,并通过/usr/lpp/cics/bin/cicstail –r cicsRegionName命令来验证CICS是否已成功启动。

    20. 一些命令

    mkgroup -’A’ id=’400′ cics

    mkgroup -’A’ id=’401′ cicsterm

    mkgroup -’A’ id=’402′ cicssm

    mkuser id=’400′ pgrp=’cics’ groups=’cicsterm,cicssm’ cics

    mkuser id=’401′ pgrp=’cics’ groups=’cicsterm,cicssm’ cicssm

    chuser fsize=’-1′ core=’-1′ cics

    chuser fsize=’-1′ core=’-1′ cicssm

    chgroup users=’oracle,root,cics’ dba

    mklv -t jfs2 -y lvcicssfs -c 2 rootvg 8

    mklv -t jfs2 -y lvcicsreg -c 2 rootvg 8

    crfs -v jfs2 -d’lvcicssfs’ -m’/var/cics_servers’ -A yes -p rw -a agblksize=’4096′

    crfs -v jfs2 -d’lvcicsreg’ -m’/var/cics_regions’ -A yes -p rw -a agblksize=’4096′

    mount /var/cics_servers

    mount /var/cics_regions

    df -k

    chown cics:cics /var/cics_servers

    chown cics:cics /var/cics_regions

    chgroup users=’cics,cicssm,root’ cics

    chgroup users=’cics,cicssm,root’ cicsterm

    export LANG=en_US

    export PATH=$PATH:/usr/lpp/cics/bin:/usr/lpp/cicssm/bin

    export LIBPATH=$LIBPATH:/usr/lpp/cics/lib:/usr/lpp/cicssm/lib

    export NLSPATH=/usr/lpp/cics/msg/%L/%N:/usr/lpp/cics/msg/C/%N:/usr/lpp/cicssm/msg/en_US/%N:/usr/lib/nls/msg/%L/%N

    export PATH=$PATH:/usr/vac/bin:/usr/vacpp/bin

    mkuser id=’402′ pgrp=’cics’ groups=’cicsterm,cicssm’ SFS_SERV

    mklv -t raw -y sfs_SFS_SERV -c 2 rootvg 8

    mklv -t raw -y log_SFS_SERV -c 2 rootvg 8

    chown SFS_SERV:cics /dev/*sfs_SFS_SERV /dev/*log_SFS_SERV

    /usr/lpp/cics/bin/cicsdefaultservers

    cicssfscreate -v /.:/cics/sfs/sfsServerName

    chuser home=’/var/cics_servers/SSD/cics/sfs/sfsServerName‘ SFS_SERV

    chown SFS_SERV:cics /var/cics_servers/SSD/cics/sfs/sfsServerName

    /usr/lpp/cics/bin/cicssfs -v /.:/cics/sfs/sfsServerName StartType=cold

    /usr/lpp/encina/bin/sfsadmin list lvols -server /.:/cics/sfs/sfsServerName

    cicsdefault -r test

    cicsupdate -c rd -r test DefaultFileServer=/.:/cics/sfs/sfsServerName

    cicsadd -c ld -r test ldtest TCPService=’ldtest’

    分类: CICS 标签:

    又见OutOfMemory——一次内存溢出故障诊断全过程

    2010年11月9日 admin 7 条评论

    这是一个几月前的案例,问题比较典型,在分析和事后学习的过程中让我对本地内存溢出有了一定的了解。在此和大家分享。

    先说一下背景,应用环境是AIX5.3+WebSphere6.0.2.37。在今年的一季度曾发生过几次OOM故障,当时通过几次内存参数优化,最后确定为“-Xgcprolicy:gencon –Xms512m –Xmx1280m –Xmn200m”,此后稳定了半年,直到此次再发生应用宕机。

    赶到现场,发现profiles目录下生成有javacore和heapdump文件,Javacore的第一行“Cause of thread dump : Dump Event "systhrow" (00040000) Detail "java/lang/OutOfMemoryError" received”表明了宕机的原因是OOM,但是令我困惑的是这段内容:

    0SECTION       MEMINFO subcomponent dump routine
    NULL           =================================
    1STHEAPFREE    Bytes of Heap Space Free: 818cb70
    1STHEAPALLOC   Bytes of Heap Space Allocated: 20000000

    在分配的512MB(十六进制20000000)的堆空间中,有129MB(818cb70)空闲空间,按理说,这种情况下不该发生OutOfMemory。就算有申请一个大对象,同时JVM堆的新生代由于碎片原因没有连续空间满足要求,那么应该发生堆扩展,所以此次内存溢出不是堆(Heap)溢出,GC日志的分析也支持了这一点。

    既然Javacore无法得到有用信息,我把目光转向了SystemErr.log,在对应日期的地方,我发现了大量如下报错:

    [8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr     R Exception in thread "WebContainer : 1" java.lang.RuntimeException: java.lang.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 11
    [8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr     R     at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:801)
    [8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr     R     at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)
    [8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr     R     at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
    [8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr     R Caused by: java.lang.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 11
        at java.lang.Thread.startImpl(Native Method)
        at java.lang.Thread.start(Thread.java:980)
        at com.ibm.ws.util.ThreadPool.addThread(ThreadPool.java:630)
        at com.ibm.ws.util.ThreadPool$3.run(ThreadPool.java:1148)
        at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:63)
        at com.ibm.ws.util.ThreadPool.execute(ThreadPool.java:1146)
        at com.ibm.ws.util.ThreadPool.execute(ThreadPool.java:1040)
        at com.ibm.ws.runtime.WSThreadPool.execute(WSThreadPool.java:151)
        at com.ibm.io.async.ResultHandler.startHandler(ResultHandler.java:248)
        at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:570)
        at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)
        at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)

    在事后的学习中,我知道“Java.lang.OutOfMemoryError: unable to create native thread” 这样的异常是在说,本地内存耗尽,从而新的线程无法创建。而在当时我第一感觉是操作系统参数设置问题,之前我曾写过一篇由于nofile参数导致Too many open file的故障。于是我运行如下命令

    #lsattr -El sys0 -a maxuproc
    maxuproc 128 Maximum number of PROCESSES allowed per user True

      然后运行chgsys修改默认的128为1024,这里我犯了一个错误,WebSphere单个Server就是一个Java进程,错误日志里是不能创建一个thread,而非process,与Oracle会创建多个oracle进程不一样。果然两天后又出现了同样的问题。
      这一次的SystemErr日志中,除了上述的内容,还多了

    [8/24/10 9:55:19:813 GMT+08:00] 00000036 SystemErr     R Exception in thread "WebContainer : 4" java.lang.RuntimeException: java.lang.OutOfMemoryError: Unable to allocate 8192 bytes of direct memory after 5 retries
    [8/24/10 9:55:19:813 GMT+08:00] 00000036 SystemErr     R     at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:801)
    [8/24/10 9:55:19:813 GMT+08:00] 00000036 SystemErr     R     at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)
    [8/24/10 9:55:19:813 GMT+08:00] 00000036 SystemErr     R     at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
    [8/24/10 9:55:19:813 GMT+08:00] 00000036 SystemErr     R Caused by: java.lang.OutOfMemoryError: Unable to allocate 8192 bytes of direct memory after 5 retries
        at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:197)
        at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:303)
        at com.ibm.ws.buffermgmt.impl.WsByteBufferPoolManagerImpl.allocateBufferDirect(WsByteBufferPoolManagerImpl.java:656)
        at com.ibm.ws.buffermgmt.impl.WsByteBufferPoolManagerImpl.allocateCommon(WsByteBufferPoolManagerImpl.java:570)
        at com.ibm.ws.buffermgmt.impl.WsByteBufferPoolManagerImpl.allocateDirect(WsByteBufferPoolManagerImpl.java:506)
        at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:498)
        at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)
        at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
    Caused by: java.lang.OutOfMemoryError
        at sun.misc.Unsafe.allocateMemory(Native Method)
        at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:184)
        … 7 more

    我们可以看到是由于DirectByteBuffer无法分配导致的内存溢出,而Native Method指明了这是“本地”的溢出。通过这两个关键字,我查到了IBM的一份BUG记录:PK31010: OUTOFMEMORYERROR DUE TO DIRECTBYTEBUFFER,但是我的版本已是最新,无奈继续搜寻。

    Troubleshooting native memory issues这份文档中,介绍了3种在WebSphere中最常见的导致OOM的原因。其中第二个DirectByteBuffer use就是我们问题的症结。

    Java 1.4 中添加的新 I/O (NIO) 类引入了一种基于通道和缓冲区来执行 I/O 的新方式。就像 Java 堆上的内存支持 I/O 缓冲区一样,NIO 添加了对直接 ByteBuffer 的支持(使用java.nio.ByteBuffer.allocateDirect() 方法进行分配),ByteBuffer 受本机内存而不是 Java 堆支持。直接 ByteBuffer 可以直接传递到本机操作系统库函数,以执行 I/O — 这使这些函数在一些场景中要快得多,因为它们可以避免在 Java 堆与本机堆之间复制数据。

        对于在何处存储直接 ByteBuffer 数据,很容易产生混淆。应用程序仍然在 Java 堆上使用一个对象来编排 I/O 操作,但持有该数据的缓冲区将保存在本机内存中,Java 堆对象仅包含对本机堆缓冲区的引用。非直接 ByteBuffer 将其数据保存在 Java 堆上的 byte[] 数组中。下图展示了直接与非直接 ByteBuffer 对象之间的区别:

         直接与非直接 java.nio.ByteBuffer 的内存拓扑结构

    ByteBuffer 内存安排

        直接 ByteBuffer 对象会自动清理本机缓冲区,但这个过程只能作为 Java 堆 GC 的一部分来执行,因此它们不会自动响应施加在本机堆上的压力。GC 仅在 Java 堆被填满,以至于无法为堆分配请求提供服务时发生,或者在 Java 应用程序中显式请求它发生(不建议采用这种方式,因为这可能导致性能问题)。

        发生垃圾收集的情形可能是,本机堆被填满,并且一个或多个直接 ByteBuffers 适合于垃圾收集(并且可以被释放来腾出本机堆的空间),但 Java 堆几乎总是空的,所以不会发生垃圾收集。

    摘自《理解JVM如何使用Windows和Linux上的本机内存》

    解决此问题的方法,在文档中给出的是禁止异步A/O,通过在Web Container中设置参数来避免上节中所出现的由于Java堆空闲而不发生垃圾回收,导致本地堆撑满的情况。

      Servers -> Application Servers -> serverName -> Web Container Settings -> Web Container -> Custom Properties:
      Press New:
      Add the following pair:

        Name: com.ibm.ws.webcontainer.channelwritetype
        Value: sync

      Press OK, and then save the configuration.

      添加此属性后应用又恢复正常,但是原先提高性能的特性反而导致内存溢出,违背了初衷,现在的做法只能算一个妥协。我会继续查找此问题的解决方法,最不济也要有个使用NIO的Best Practice。

    文档中另两个容易导致本地堆OOM的原因是:

    过大的堆上限

    Memory layout of a vm in the os

    我们知道32位机器单个进程可以访问的内存地址空间为4G,如右图所示,但实际情况下Windows系统由于内核态和用户态的划分,用户态只有2G的空间,Linux和AIX的可用空间大一点,但也在3G左右。,由于JVM实例进程寻址是一定的,所以Heap大小和Native Area此消彼长。而Native Area中有一部分就是供给线程的内存空间。

    “应用程序中的每个线程都需要内存来存储器堆栈(用于在调用函数时持有局部变量并维护状态的内存区域)。每个 Java 线程都需要堆栈空间来运行。根据实现的不同,Java 线程可以分为本机线程和 Java 堆栈。除了堆栈空间,每个线程还需要为线程本地存储(thread-local storage)和内部数据结构提供一些本机内存。堆栈大小因 Java 实现和架构的不同而不同。一些实现支持为 Java 线程指定堆栈大小,其范围通常在 256KB 到 756KB 之间。”

    1.5后一般线程堆栈大小为1M,“对于拥有数百个线程的应用程序来说,线程堆栈的总内存使用量可能非常大。如果运行的应用程序的线程数量比可用于处理它们的处理器数量多,效率通常很低,并且可能导致糟糕的性能和更高的内存占用”(摘自《理解JVM如何使用Windows和Linux上的本机内存》)

    解决此问题的方法:设置恰当的JVM最大堆,32位不要超过1.5G;设置恰当的线程池大小(一般50~100),当线程使用较多时, 使用-Xss256k参数设置线程指定堆栈大小(IBM JDK还可以使用-Xmso ××k来设置Stack size for OS Threads 32-bit);更换64位的JDK。

    第三个原因是线程池的TLS泄漏

    这个现象我倒没见到过,如果你的thread dump里下面三个属性里的值有大于300,那么就要注意了

    "WebContainer : 1003" (TID:0×37D62000
    "Default : 338" (TID:109934D0
    "TCPChannel.DCS : 303" (TID:0×4D720000

    解决的方法是设置线程池的最小最大值一致。

    总有一些世界观,是傻逼呵呵地矗立在那里的

    2010年8月15日 admin 1 条评论

    上一篇标题是be foolish,这一篇就就要写idiot了。《Three Idiots》,或者又叫《三傻大闹宝莱坞》,让无聊的周末晚上,变得丰富多彩起来。

    这是一部校园青春片,归类在喜剧片里,于是自然的让屏幕前的我乐不可支,但如果仅仅如此,那么它就是美国校园喜剧的翻版,我也不会在这个技术博里分享观看后感受。作为同样经历经济高速发展的邻居——印度,这部电影所探讨的理想与现实、爱情与金钱、注重结果还是过程,深深的感触到了我。

    噪鹃从来不自己筑巢,他只在别人的巢里下蛋,要孵蛋的时候他们会怎样?他们会把其它的蛋从巢里挤出去,竞争结束了,他们的生命从谋杀开始,这就是大自然——要么竞争,要么死……

    丛林法则,优胜劣汰,“病毒”的开场白在父母送你去补习班的时候,在你选择大学专业的时候,会听到各种各样类似的版本。在大学里,为了绩点而奋斗,只看为考试而划重点的内容,不是为了知识,而是为了“从这5年后,当你看到你的朋友买车买房时不会诅咒自己。”

    一定要让自己活在“高压锅”里么?某种程度上是的,当你的父母把唯一的空调装在你的房间里让你安心学习,把自己年轻时的遗憾作为目标寄托在你的身上时,当你家里有个生病的父亲、没有嫁妆出嫁的姐姐、以及辛苦照顾这个家的母亲时,我们很难有勇气说出:过自己喜欢过的生活、做自己喜欢做的事,哪怕钱赚的再少只要自己觉得幸福就足够了(这应该就是所谓的责任感使命感吧)。所以我们像男主角的两个朋友,要么生活在“虚伪”里,要么生活在“恐惧”中。

    于是我们一个个的“成功”了,但是“理想”这种东西,要么戒了,要么又作为自己的遗憾,硬加到自己的孩子身上。

    影片中的爱情,则是以一场订婚一场逃婚来演绎,笔墨不多,却同样有内心抉择的痛苦。是嫁给一个生活贴了标签的成功男士,还是去找能让心情像头发一般飘逸起来的男主角?影片中女主当然选择了后者,但面对现实的生活压力,有多少人能无视暂时的闲言碎语,有多少姻缘因为经济的原因而拆散,又有多少夫妻在坚硬的钢筋水泥的城市里扎不下根来。

    所以当影片放到Farhan他爸爸说到:把(电脑)退了,换一部专业摄像机,钱还不够就向我要的时候。放到Raju Rastogi说出“断了两条腿,我才真正站了起来,获得这样的生活态度不容易,我不会放弃”的时候,当病毒主任最终也说出“做你想做的”,并把32年都没送出的太空笔插到Rancho的衣领上时,我再也无法控制自己的眼泪不夺眶而出。

    不过看完片后思及自身,又让我感到另外一种悲哀——我不知道自己除了工作之外,还有什么值得投入精力的爱好,不知道自己真正想要的生活是什么。乔治奥威尔痛苦的是“英国人的[阶级]烙印是打在舌头上的”,“他的一切疙瘩都来自于这个事实:他认为他应该去爱他的同胞,但是他连同他们随便交谈都做不到。”而我则是“认为应该去过自己喜欢的生活,但是却连什么是自己喜欢的都不知道”。长年的填鸭式的教育,父母的期盼,老娘舅里形形色色的人生故事,让我以为生活就是如此。看来我们都需要一个像Rancho这样的朋友,告诉我们世界上还有种不合时宜的世界观,也能通向成功。

    一个没有一出生就背负使命的园丁的儿子很少见,那至少让我们记住这句话“Follow excellence,Success will chase you !"

    分类: 生活感想 标签: