仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 637|回复: 14
打印 上一主题 下一主题

[学习教程] JAVA编程:罕见的Java成绩排查办法仓酷云

[复制链接]
爱飞 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:23:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
在ruby里才是一切皆对象。当然我不并不是很了解ruby,但是ruby确实是将语法简化得很好。以下是Java使用在运转经常见的一些成绩,总结了运转时黑盒体例的一些排查办法,也但愿看到的同砚能赐与增补,不管是增补碰着的成绩,仍是增补办理办法。
类装载的相干成绩
写过Java代码的同砚估量都碰着过ClassNotFoundException/NoClassDefFoundError/NoSuchMethodException(另有一个罕见的ClassCastException就不在这里说了)。
当碰着ClassNotFoundException/NoClassDefFound时,假如很断定这个class应当是从哪一个路径装载的,则能够往响应的路径找下是不是有对应的class文件存在,比方web使用一般会在*.war(ear)/WEB-INF/lib或classes目次下,关于lib下的jar包,可经由过程写个小剧本jar-tvf的体例找找;
如不断定class是从哪装载的,则能够先看看日记里是不是有仓库信息,假如有的话则能够看到详细是哪一个ClassLoader完成在装载class,以后则能够经由过程www.grepcode.com或jar包反编译(保举一个挺好用的反编译工具)看看详细是从哪装载的class;
如日记中没有,则能够用btrace来跟踪下抛出以上两个非常的仓库信息,btrace剧本相似以下:
1
2
3
4
5
6
7
8
9
10
11
importstaticcom.sun.btrace.BTraceUtils.*;
importcom.sun.btrace.annotations.*;
@BTracepublicclassTrace{
@OnMethod(
clazz="java.lang.ClassNotFoundException",
method="<init>"
)
publicstaticvoidtraceExecute(){
jstack();
}
}

拿到仓库信息后,能够持续利用下面的办法举行排查,在确认了class装载的地位后,则可将响应的class/jar加上便可。
这里另有个NoClassDefFoundError排查的case,感乐趣的话能够看看。
当碰着NoSuchMethodException时,一般是因为不存在必要的class版本或class版本抵触酿成的,在这类情形下,可经由过程在启动参数上增添-XX:+TraceClassLoading,重启后在日记里看看此class是在哪load的,然后能够在对应的路径下用jar-tvf找找是否是有准确的版本的jar存在,一般大概会发明是版本抵触酿成的,关于版本抵触的成绩一般必要删失落有抵触的版本的jar,关于没有准确版本的,则必要用准确版本的jar交换失落(固然,这类一般还会呈现一些恶心的成绩,比方和容器/框架的jar抵触等)。
cpuus损耗高
当呈现cpuus损耗高时,一般的排查办法以下。
从履历下去说,有些时分是因为频仍cmsgc或fgc酿成的(频仍的意义是差未几每次cmsgc或fgc一停止后又立即持续),在gclog是纪录的情形下(-Xloggc:),可经由过程gclog看看,假如没翻开gclog,可经由过程jstat-gcutil来检察,如是gc频仍酿成的,则可跳到前面的内存成绩|GC频仍部分看排查办法。
如不是下面的缘故原由,可以使用top-H检察线程的cpu损耗情况,这里有大概会看到有一般线程是cpu损耗的主体,这类情形一般会对照好办理,可依据top看到的线程id举行十六进制的转换,用转换出来的值和jstack出来的java线程仓库的nid=0x[十六进制的线程id]举行联系关系,便可看到此线程究竟在做甚么举措,这个时分必要进一步的往排查究竟是甚么缘故原由酿成的,比方有多是正则盘算,有多是很深的递回或轮回,也有多是毛病的在并发场景利用HashMap等,比方这里另有一段随即天生字符串的耗cpu的代码case。
如top-H看到的损耗cpu的线程是不休变更的,就对照贫苦了,有个同砚写了个剧本主动的往经由过程top-H看到的损耗cpu的线程找到对应的Java线程仓库,在这类情形下能够用这个剧本往尝尝,假如看到的线程仓库的确是对照耗cpu的举措,则基础能够定位到。
如仍旧看不出,则能够实验多jstack看看,然后多看看是不是常常有一些耗cpu的举措在分歧的线程不休的呈现。
如可以使用perf,则可用perftop看看cpu损耗的热门,不外默许的版本上只能看到jit后的代码,因而大概会对照难对应到详细的代码,这里有一个基于perf排查的Java使用cpuus诡异征象的case。
总结来讲,cpuus损耗高的成绩排查仍是有必定庞大性,比方之前我碰着过反序列化的对象对照年夜,哀求又十分频仍,招致cpuus损耗增高了良多,但事先的呆板内核版本不敷,不撑持perf,从jstack等等上都看不出甚么,厥后是因为从营业监控的变更上才排查出成绩。
内存成绩
只管JVM是主动办理内存的分派和接纳的,但Java程序员们仍是会常常碰着林林总总的内存成绩。
最多见的第一个成绩是java.lang.OutOfMemoryError,估量写Java的同砚都碰着过。
在日记中大概会看到java.lang.OutOfMemoryError:Unabletocreatenewnativethread,能够先统计下今朝的线程数(比方ps-eLf|grepjava-c),然后能够看看ulimit-u的限定值是几,如线程数已到达限定值,如限定值可调剂,则可经由过程调剂限定值来办理;如不克不及调限定值,大概创立的线程已良多了,那就必要看看线程都是那里创立出来的,一样可经由过程btrace来查出是那里创立的,剧本相似以下:
1
2
3
4
5
6
7
8
9
10
11
importstaticcom.sun.btrace.BTraceUtils.*;
importcom.sun.btrace.annotations.*;
@BTracepublicclassTrace{
@OnMethod(
clazz="java.lang.Thread",
method="start"
)
publicstaticvoidtraceExecute(){
jstack();
}
}

在找到是那里创立形成了后,以后就能够想举措办理了,比方这类情形下罕见的有多是用了Executors.newCachedThreadPool这类来创立了一个没限定巨细的线程池。
另有一种多是ulimit-u的限定还没到,内存也余暇,但仍旧创立不了,这有多是因为在2.6.18/32内核上kernel.pid_max默许的32768酿成的,这个值实在间接限定了最多能创立的线程数就是32768(即便ulimit-u的值比这年夜也没用)。
java.lang.OutOfMemoryError:HeapSize或GCoverheadlimitexceeded也是罕见的征象,在呈现了这两种征象的情形下,最主要的是dump出内存,一种办法是经由过程在启动参数上增添-XX:+HeapDumpOnOutOfMemoryError,另外一种办法是在当呈现OOM时,经由过程jmap-dump猎取到内存dump,在猎取到内存dump文件后,可经由过程MAT举行剖析,但一般来讲仅仅靠MAT大概还不克不及间接定位到详细使用代码中哪一个部分酿成的成绩,比方MAT有大概看到是某个线程创立了很年夜的ArrayList,但如许是不敷以办理成绩的,以是一般还必要借助btrace来定位到详细的代码,能够看看这两个OOM排查的case。
java.lang.OutOfMemoryError:PermGenSpace,当碰着这个征象时,能够经由过程调剂permgensize来尝尝,假如缩小了一点后仍是不休的损耗,则能够经由过程btrace来跟踪下装载class的征象,剧本相似以下:
1
2
3
4
5
6
7
8
9
10
11
importstaticcom.sun.btrace.BTraceUtils.*;
importcom.sun.btrace.annotations.*;
@BTracepublicclassTrace{
@OnMethod(
clazz="java.lang.ClassLoader",
method="defineClass"
)
publicstaticvoidtraceExecute(){
jstack();
}
}

另有一种OOM是nativeOOM,就是物理内存被耗光,关于这类征象,办理起来会贫苦一些,从履历下去说,NativeOOM有很也许率是因为毛病利用Deflater/Inflater酿成的,以是在碰着这类征象时,能够先用btrace跟进下看看利用了Deflater/Inflater的有无显式往挪用end办法;别的一种罕见的缘故原由是利用DirectByteBuffer的场景(比方NIO框架等),如利用了DirectByteBuffer的对象是对照长存活的,当其被转到旧生代后,在fgc没触发前,实在其占用的JVM堆外内存是不会被开释的,在这类情形下,能够做的一个实验是先强迫实行几回fgc(jmap-histo:live),然后看看堆外内存的利用是否是下落了,假如下落了则申明是这个成绩,关于这类成绩,能够用的一个办理计划是增添一个启动参数:-XX:MaxDirectMemorySize=500m来完成当DirectByteBuffer利用到500m后自动触发fgc往返收(究竟设置成多年夜使用能够本人调剂)。
如下面两招都没用,则必要挂上googleperf-tools来跟踪下看看究竟是那里在malloc,不外这里看到的是c仓库上的工具,因而必要本人想举措依据这个对应到java的代码上往。
关于nativeOOM,这篇文章里有一些详细排查的case。
除OOM外,另有大概会碰着GC频仍的成绩(有良多同砚会问我,究竟甚么算频仍,我以为基础上假如每隔10s或更短工夫就来一次cmsgc或fullgc才算得上吧)。
GC频仍的征象呈现时,假如发明cmsgc或fullgc后,存活的对象一直良多,这类情形下能够经由过程jmap-dump来猎取下内存dump文件,然后经由过程MAT/btrace来定位到详细的缘故原由。
如cmsgc或fullgc频仍,但触发时old另有余暇空间,这类情形下有大概会是因为失望战略形成,详细能够看看这篇文章里的几个cases,这类情形下一般的办理办法能够是调年夜old或减小young。
如不是失望战略酿成的,关于接纳cmsgc的情形,另有多是cmsgc的碎片成绩酿成的,这类情形下能够经由过程强迫实行下jmap-histo:live来触发fgc,不外悲催的是cmsgc的碎片成绩是无解的,临时只能靠强迫触发fgc等来制止在岑岭期时呈现成绩。
关于cmsgc而言,另有大概会呈现promotionfailed或concurrentmodefailure成绩,详细也能够看看下面那篇文章的cases。
Java历程crash或加入
Java历程crash或无端加入也是会碰着的征象,关于历程crash,默许情形下jdk会天生hs_err[pid].log的文件,coredump翻开的话也会天生coredump文件,当历程crash产生时,能够先看看hs_err[pid].log,如没找到此文件,但有coredump文件,有大概的缘故原由是代码中呈现了无穷递回或逝世轮回,可经由过程jstack
1

[coredump文件]来提掏出java的线程仓库,从而详细定位到详细的代码;若有hs_err[pid].log和coredump文件,则必要详细缘故原由详细排查,这个对照贫苦,罕见的大概会有下面的nativeoom(另有多是32bit呆板,但java历程已请求了凌驾3g的地点空间),某些代码jit编译出成绩了(可经由过程指定某些代码不让jit编译来制止,但会影响功能:-XX:CompileCommand=exclude,类名/办法名)等。
在下面的招还有效时,能够实验dmesg看看是否是体系出了甚么成绩或体系自动杀失落过历程(比方内存超越限定等),仍旧没找到缘故原由的话必要往翻翻使用的日记,看看是否是能找到甚么线索,由于有些时分是使用上自动加入了(关于使用自动加入的成绩可经由过程btrace来排查是否是有自动挪用过System.exit)。

唉!都是钱闹的1.Swing和.net网页编程开发比较------从市场份额看.net网页编程开发主要占据大部分的中小型和中型的的桌面开发,原因是它封装了很多工具
透明 该用户已被删除
沙发
发表于 2015-1-20 23:48:43 | 只看该作者
象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。
兰色精灵 该用户已被删除
板凳
发表于 2015-1-24 22:09:09 | 只看该作者
J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。
深爱那片海 该用户已被删除
地板
发表于 2015-1-26 20:35:58 | 只看该作者
Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台
不帅 该用户已被删除
5#
发表于 2015-1-30 22:57:56 | 只看该作者
Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。
分手快乐 该用户已被删除
6#
发表于 2015-2-6 16:35:05 | 只看该作者
如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
若相依 该用户已被删除
7#
发表于 2015-2-7 12:08:46 | 只看该作者
你快去找一份Java的编程工作来做吧(如果是在校学生可以去做兼职啊),在实践中提高自己,那才是最快的。不过你得祈祷在公司里碰到一个高手,而且他 还愿意不厌其烦地教你,这样好象有点难哦!还有一个办法就是读开放源码的程序了。我们知道开放源码大都出自高手,他们设计合理,考虑周到,再加上有广大的程序员参与,代码的价值自然是字字珠叽,铿锵有力(对不起,偶最近《金装四大才子》看多了)。
变相怪杰 该用户已被删除
8#
发表于 2015-2-16 07:52:49 | 只看该作者
自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。
精灵巫婆 该用户已被删除
9#
发表于 2015-2-26 06:38:19 | 只看该作者
如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
灵魂腐蚀 该用户已被删除
10#
发表于 2015-2-28 16:47:52 | 只看该作者
一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从
爱飞 该用户已被删除
11#
 楼主| 发表于 2015-3-4 04:12:42 | 只看该作者
[url]http://www.jdon.com/[/url]去下载,或到同济技术论坛的服务器[url]ftp://nro.shtdu.edu.cn[/url]去下,安装上有什么问题,可以到论坛上去提问。
老尸 该用户已被删除
12#
发表于 2015-3-11 16:24:37 | 只看该作者
让你能够真正掌握接口或抽象类的应用,从而在原来的Java语言基础上跃进一步,更重要的是,设计模式反复向你强调一个宗旨:要让你的程序尽可能的可重用。
简单生活 该用户已被删除
13#
发表于 2015-3-11 17:08:17 | 只看该作者
Java是一种计算机编程语言,拥有跨平台、面向对java
小魔女 该用户已被删除
14#
发表于 2015-3-13 07:07:12 | 只看该作者
当然你也可以参加一些开源项目,一方面可以提高自己,另一方面也是为中国软件事业做贡献嘛!开发者在互联网上用CVS合作开发,用QQ,MSN,E-mail讨论联系,天南海北的程序员分散在各地却同时开发同一个软件,是不是很有意思呢?
飘飘悠悠 该用户已被删除
15#
发表于 2015-3-20 15:35:11 | 只看该作者
一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-6-2 23:16

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表