作者:kelly最爱梁君诺_795 | 来源:互联网 | 2022-12-28 15:45
java报错noelementdefined.element:Bank定位不清晰。点击报错位置返回发生异常的代码,仔细查看有关Java的定位是否写错,或者调用是否用对ElmentN
java报错no element defined.element:Bank
定位不清晰。点击报错位置返回发生异常的代码,仔细查看有关Java的定位是否写错,或者调用是否用对ElmentNotFoundException原因是程序执行太快,元素还没出现,需要等待元素出现,这时候可以试一下Threadsleep方法,如果成功,再用智能的wait方法来解决问题,因为iframe定位不到元素,也找不到iframename,则用firebug,找到对应iframe,右键复制xpath。
如何定位:java.lang.OutOfMemoryError:GC overhead limit exceeded
Java常见的几种内存溢出及解决方法【情况一】:java.lang.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,一个原因是真不够(如递归的层数太多等),另一个原因是程序中有死循环;如果是java堆内存不够的话,可以通过调整JVM下面的配置来解决:-Xms3062m-Xmx3062m【情况二】java.lang.OutOfMemoryError:GCoverheadlimitexceeded【解释】:JDK6新增错误类型,当GC为释放很小空间占用大量时间时抛出;一般是因为堆太小,导致异常的原因,没有足够的内存。【解决方案】:1、查看系统是否有使用大内存的代码或死循环;2、通过添加JVM配置,来限制使用内存:-XX:-UseGCOverheadLimit【情况三】:java.lang.OutOfMemoryError:PermGenspace:这种是P区内存不够,可通过调整JVM的配置:-XX:MaxPermSize=128m-XXermSize=128m【注】:JVM的Perm区主要用于存放Class和Meta信息的,Class在被Loader时就会被放到PermGenspace,这个区域成为年老代,GC在主程序运行期间不会对年老区进行清理,默认是64M大小,当程序需要加载的对象比较多时,超过64M就会报这部分内存溢出了,需要加大内存分配,一般128m足够。
【情况四】:java.lang.OutOfMemoryError:Directbuffermemory调整-XX:MaxDirectMemorySize=参数,如添加JVM配置:-XX:MaxDirectMemorySize=128m【情况五】:java.lang.OutOfMemoryError:unabletocreatenewnativethread【原因】:Stack空间不足以创建额外的线程,要么是创建的线程过多,要么是Stack空间确实小了。
【解决】:由于JVM没有提供参数设置总的stack空间大小,但可以设置单个线程栈的大小;而系统的用户空间一共是3G,除了Text/Data/BSS/MemoryMapping几个段之外,Heap和Stack空间的总量有限,是此消彼长的。因此遇到这个错误,可以通过两个途径解决:1.通过-Xss启动参数减少单个线程栈大小,这样便能开更多线程(当然不能太小,太小会出现StackOverflowError);2.通过-Xms-Xmx两参数减少Heap大小,将内存让给Stack(前提是保证Heap空间够用)。
如何快速定位错误出现的位置
2.
java 程序运行错误怎么办?
看是发生了什么错误,大多数错误都可以通过改写原编码来解决。
程序的错误可以抽象分为三类:语法错误、运行错误和逻辑错误。
1、语法错误
是指由于编程中输入不符合语法规则而产生的。
程序编译就通不过,程序不能运行起来。此类错误最简单,调试起来比较容易
例如:表达式不完整、缺少必要的标点符号、关键字输入错误、数据类型不匹配、循环语句或选择语句的关键字不匹配等。通常,编译器对程序进行编译的过程中,会把检测到的语法错误以提示的方式列举出来,又称为编译错误。语法错误的调试,则可以由集成开发环境提供的调试功能来实现,在程序进行编译时,编译器会对程序中的语法错误进行诊断。
编译诊断的语法错误分为3中:致命错误、错误和警告。(1)致命错误:这个错误大多是编译程序内部发生的错误,发生这类错误时,编译被迫中止,只能重新启动编译程序,但是这类错误很少发生,为了安全,编译前最好还是先保存程序。(2)错误:这个错误通常是在编译时,语法不当所引起的。
例如:括号不匹配,变量未声明等。产生这类错误时,编译程序会出现报错提示,我们根据提示对源程序进行修改即可。这类错误是出现最多的。
(3)警告:是指被编译程序怀疑有错,但是不确定,有时可强行通过。例如:没有加void声明的主函数没有返回值,double数据被转换为float类型等。这些警告中有些会导致错误,有些可以通过。
常规解决方法:此类错误一般程序编译系统会自动提示相应的错误地点和错误原因,比如哪一行代码少了个括号等诸如此类的提示,常见的错误,看懂直接改正即可,如果是看不懂原因,可以将错误提示信息输入搜索引擎查找一下,一般都能找到具体的解决办法。或者有些编程平台会本身提供一个本地或者在线的信息库,提供详细的错误原因和解决办法,比如微软的.NET开发平台。
2、运行错误
指程序在运行过程中出现的错误。程序通过语法错误检测,但是运行的时候出现错误,导致程序被迫终止,此类错误有特定的发生条件,因此能够准确的定位错误代码段,因而调试也比较方便。
例如:除法运算时除数为0 、数组下标越界、文件打不开、磁盘空间不够、数据库连接错误等。
此类错误发生时,编译平台一般也会提示相应的信息,对于常规的错误会有比较精确地提示,但有时提示的错误原因会比较模糊,但因为此类错误一般在程序运行时,只在特定的条件下才会发生,所以根据错误发生的条件,能够大致判断程序出错的代码段,结合错误的原因,也能比较方便的调试出错误。
3、逻辑错误
程序运行后,没有得到设计者预期的结果,这就说明程序存在逻辑错误。这种错误在语法上是有效的,但是在逻辑上是错误的。
程序运行了,也没有出错,但是执行出来的结果不是用户想要的,分为两种情况:
A、 能够看出错误:比如查询工资大于5000的人员名单,却出现了3000的;
B、 看不出错误,直到因缘际会发现程序肯定出错了,后果很严重:比如进行一个符合大型运算,把某个常数输入错了,最后的结果人工无法判断对错,又以该结果进行其它的运算等等,最后发现错了误差过大,就得从头排查错误。
如何定位java内存泄露
1、为什么会发生内存泄漏
Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。
编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时,无法从Heap中获取足够的内存分配给对象,这时候就会导致内存溢出。
而出现内存泄露的地方,一般是不断的往容器中存放对象,而容器没有相应的大小限制或清除机制。
容易导致内存溢出。当服务器应用占用了过多内存的时候,如何快速定位问题呢?现在,Eclipse MAT的出现使这个问题变得非常简单。EclipseMAT是著名的SAP公司贡献的一个工具,可以在Eclipse网站下载到它,完全免费的。要定位问题,首先你需要获取服务器jvm某刻内存快照。
jdk自带的jmap可以获取内存某一时刻的快照,导出为dmp文件后,就可以用Eclipse MAT来分析了,找出是那个对象使用内存过多。
2、内存泄漏的现象:
常常地,程序内存泄漏的最初迹象发生在出错之后,在你的程序中得到一个OutOfMemoryError。这种典型的情况发生在产品环境中,而在那里,你希望内存泄漏尽可能的少,调试的可能性也达到最小。
也许你的测试环境和产品的系统环境不尽相同,导致泄露的只会在产品中暴露。这种情况下,你需要一个低负荷的工具来监听和寻找内存泄漏。同时,你还需要把这个工具同你的系统联系起来,而不需要重新启动他或者机械化你的代码。
也许更重要的是,当你做分析的时候,你需要能够同工具分离而使得系统不会受到干扰。一个OutOfMemoryError常常是内存泄漏的一个标志,有可能应用程序的确用了太多的内存;这个时候,你既不能增加JVM的堆的数量,也不能改变你的程序而使得他减少内存使用。但是,在大多数情况下,一个OutOfMemoryError是内存泄漏的标志。
一个解决办法就是继续监听GC的活动,看看随时间的流逝,内存使用量是否会增加,如果有,程序中一定存在内存泄漏。
3、发现内存泄漏
1. jstat -gc pid
可以显示gc的信息,查看gc的次数,及时间。
其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。
2.jstat -gccapacity pid
可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,
如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,
PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。
其他的可以根据这个类推,OC是old内纯的占用量。
3.jstat -gcutil pid
统计gc信息统计。
4.jstat -gcnew pid
年轻代对象的信息。
5.jstat -gcnewcapacity pid
年轻代对象的信息及其占用量。
6.jstat -gcold pid
old代对象的信息。
7.stat -gcoldcapacity pid
old代对象的信息及其占用量。
8.jstat -gcpermcapacity pid
perm对象的信息及其占用量。
9.jstat -class pid
显示加载class的数量,及所占空间等信息。
10.jstat -compiler pid
显示VM实时编译的数量等信息。
11.stat -printcompilation pid
当前VM执行的信息。
一些术语的中文解释:
S0C:年轻代中第一个survivor(幸存区)的容量(字节)S1C:年轻代中第二个survivor(幸存区)的容量(字节)S0U:年轻代中第一个survivor(幸存区)目前已使用空间(字节)S1U:年轻代中第二个survivor(幸存区)目前已使用空间(字节)EC:年轻代中Eden(伊甸园)的容量(字节)EU:年轻代中Eden(伊甸园)目前已使用空间(字节)OC:Old代的容量(字节)OU:Old代目前已使用空间(字节)PC:Perm(持久代)的容量(字节)PU:Perm(持久代)目前已使用空间(字节)YGC:从应用程序启动到采样时年轻代中gc次数YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)FGC:从应用程序启动到采样时old代(全gc)gc次数FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)GCT:从应用程序启动到采样时gc用的总时间(s)
NGCMN:年轻代(young)中初始化(最小)的大小(字节)
NGCMX:年轻代(young)的最大容量(字节)
NGC:年轻代(young)中当前的容量(字节)
OGCMN:old代中初始化(最小)的大小(字节)
OGCMX:old代的最大容量(字节)
OGC:old代当前新生成的容量(字节)
PGCMN:perm代中初始化(最小)的大小(字节)
PGCMX:perm代的最大容量(字节)
PGC:perm代当前新生成的容量(字节)
S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
O:old代已使用的占当前容量百分比
P:perm代已使用的占当前容量百分比
S0CMX:年轻代中第一个survivor(幸存区)的最大容量(字节)
S1CMX:年轻代中第二个survivor(幸存区)的最大容量(字节)
ECMX:年轻代中Eden(伊甸园)的最大容量(字节)
DSS:当前需要survivor(幸存区)的容量(字节)(Eden区已满)
TT:持有次数限制
MTT:最大持有次数限制
如果定位内存泄漏问题我一般使用如下命令:
Jstat -gcutil15469 2500 70
[root@ssss logs]# jstat -gcutil 15469 1000 300
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 1.46 26.54 4.61 30.14 35 0.872 0 0.000 0.872
0.00 1.46 46.54 4.61 30.14 35 0.872 0 0.000 0.872
0.00 1.46 47.04 4.61 30.14 35 0.872 0 0.000 0.872
0.00 1.46 65.19 4.61 30.14 35 0.872 0 0.000 0.872
0.00 1.46 67.54 4.61 30.14 35 0.872 0 0.000 0.872
0.00 1.46 87.54 4.61 30.14 35 0.872 0 0.000 0.872
0.00 1.46 88.03 4.61 30.14 35 0.872 0 0.000 0.872
1.48 0.00 5.56 4.62 30.14 36 0.874 0 0.000 0.874
1000 代表多久间隔显示一次,
100 代表显示一次。
S0 — Heap上的 Survivor space 0 区已使用空间的百分比
S1 — Heap上的 Survivor space 1 区已使用空间的百分比
E — Heap上的 Eden space 区已使用空间的百分比
O — Heap上的 Old space 区已使用空间的百分比
P — Perm space 区已使用空间的百分比
YGC — 从应用程序启动到采样时发生 Young GC 的次数
YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
FGC — 从应用程序启动到采样时发生 Full GC 的次数
FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)
如果有大量的FGC就要查询是否有内存泄漏的问题了,图中的FGC数量就比较大,并且执行时间较长,这样就会导致系统的响应时间较长,如果对jvm的内存设置较大,那么执行一次FGC的时间可能会更长。
如果为了更好的证明FGC对服务器性能的影响,我们可以使用java visualVM来查看一下:
从上图可以发现执行FGC的情况,下午3:10分之前是没有FGC的,之后出现大量的FGC。
上图是jvm堆内存的使用情况,下午3:10分之前的内存回收还是比较合理,但是之后大量内存无法回收,最后导致内存越来越少,导致大量的full gc。
下面我们在看看大量full GC对服务器性能的影响,下面是我用loadrunner对我们项目进行压力测试相应时间的截图:
从图中可以发现有,在进行full GC后系统的相应时间有了明显的增加,点击率和吞吐量也有了明显的下降。所以java内存泄漏对系统性能的影响是不可忽视的。
3、定位内存泄漏
当然通过上面几种方法我们可以发现java的内存泄漏问题,但是作为一名合格的高级工程师,肯定不甘心就把这样的结论交给开发,当然这也的结论交给开发,开发也很难定位问题,为了更好的提供自己在公司的地位,我们必须给开发工程师提供更深入的测试结论,下面就来认识一下MemoryAnalyzer.exe。java内存泄漏检查工具利器。
首先我们必须对jvm的堆内存进行dump,只有拿到这个文件我们才能分析出jvm堆内存中到底存了些什么内容,到底在做什么?
MemoryAnalyzer的用户我在这里就不一一说明了,我的博客里也有说明,下面就展示我测试的成功图:
其中深蓝色的部分就为内存泄漏的部分,java的堆内存一共只有481.5M而内存泄漏的部分独自占有了336.2M所以本次的内存泄漏很明显,那么我就来看看那个方法导致的内存泄漏:
从上图我们可以发现红线圈着的方法占用了堆内存的67.75%,如果能把这个测试结果交给开发,开发是不是应该很好定位呢。所以作为一名高级测试工程师,我们需要学习的东西太多。
虽然不确定一定是内存泄漏,但是可以准确的告诉开发问题出现的原因,有一定的说服力。