weblogic问题排查思路
内存溢出
存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak会最终会导致out of memory!
原因
内存泄露的原因有很多:
- 数据量过于庞大;
- 死循环;
- 静态变量和静态方法过多;
- 递归;
- 无法确定对象是否被引用;
- 虚拟机不回收内存等。
说白了,也就是程序运行所需的内存大于虚拟机能够提供的最大内存就发生了内存溢出(OOM),内存是否溢出取决于业务和系统的大小。(对于某些系统可能内存溢出不常见,但是对于某些其他系统,可能就常见了)
尽量避免内存溢出(解决办法)
- 优化代码:如果业务庞大,逻辑复杂,应当尽量减少全局变量的引用,使程序使用完变量后能够及时释放该引用,让GC回收,释放资源。
- 物理块:增大物理内存,然后通过JVM参数(-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m)调整虚拟机的大小(增大)。
内存溢出常见类型
java.lang.OutOfMemoryError: PermGen space
JVM管理两种类型的内存:堆和非堆。
java.lang.OutOfMemoryError: Java heap space
不健壮代码的特征和解决办法
- 尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为 null ,暗示垃圾收集器来收集该对象,防止发生内存泄露。
- 我们的程序里不可避免大量使用字符串处理,避免使用 String ,应大量使用 StringBuffer(StringBuilder)代替 ,每一个 String 对象都得独立占用内存一块区域;
- 尽量少用静态变量,因为静态变量是全局的, GC 不会回收的;
- 避免集中创建对象尤其是大对象, JVM 会突然需要大量内存,这时必然会触发 GC 优化系统内存环境;显示的声明数组空间,而且申请数量还极大。
- 尽量运用对象池技术以提高系统性能;生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。
- 不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。可以适当的使用 hashtable , vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次 new 之后又丢弃
- 一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of Memory Error 的状况,这时就大概要计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。
Java进程占用CPU过高的两种常见情况
原因
导致占用CPU过高的两种情况
- 代码中存在死循环或者接近死循环的操作;
- 快速创建大量的临时变量,导致频繁GC回收。
定位分析
使用top命令找到CPU占用高的进程;
使用top -Hp 根据进程号找到占用CPU过高的线程号;
对占用CPU过高的线程(如果存在)做16进制线程转储(jstack pid >> dump.txt; printf “%\n”);
分析dump文件(并交由业务人员分析),找到相应的线程并查询动作。
dump出java进程的堆对象使用情况
使用jmap -histo > jmap_xxx.txt
总结
找出量比较大的、且跟业务有关的对象,找到这些对象创建的地方进行分析;一般需要持续创建大量的对象,使得内存不够用时,才会频繁触发gc进行回收,gc回收时jvm有停顿,CPU也占用很高。
线程之间的切换,是很耗费性能的,所以带来CPU飙升.
新生代设置过小,也会频繁触发gc。有大对象始终根节点路径可达,无法释放,jvm在疯狂的Full GC。
Java性能分析之threaddump 和heapdump
dump的基本概念
在故障定位(尤其是out of memory)和性能分析的时候,经常会用到一些文件来帮助我们排除代码问题。这些文件记录了JVM运行期间的内存占用、线程执行等情况,这就是我们常说的dump文件。常用的有heap dump和thread dump(也叫javacore,或java dump)。我们可以这么理解:heap dump记录内存信息的,thread dump是记录CPU信息的。
**heap dump:**jmap
heap dump文件是一个二进制文件,它保存了某一时刻JVM堆中对象使用情况。HeapDump文件是指定时刻的Java堆栈的快照,是一种镜像文件。Heap Analyzer工具通过分析HeapDump文件,哪些对象占用了太多的堆栈空间,来发现导致内存泄露或者可能引起内存泄露的对象。
**thread dump:**jstack
thread dump文件主要保存的是java应用中各线程在某一时刻的运行的位置,即执行到哪一个类的哪一个方法哪一个行上。thread dump是一个文本文件,打开后可以看到每一个线程的执行栈,以stacktrace的方式显示。通过对thread dump的分析可以得到应用是否“卡”在某一点上,即在某一点运行的时间太长,如数据库查询,长期得不到响应,最终导致系统崩溃。单个的thread dump文件一般来说是没有什么用处的,因为它只是记录了某一个绝对时间点的情况。比较有用的是,线程在一个时间段内的执行情况。
两个thread dump文件在分析时特别有效,困为它可以看出在先后两个时间点上,线程执行的位置,如果发现先后两组数据中同一线程都执行在同一位置,则说明此处可能有问题,因为程序运行是极快的,如果两次均在某一点上,说明这一点的耗时是很大的。通过对这两个文件进行分析,查出原因,进而解决问题。
JDK命令行工具
-
jps:虚拟机进程状况工具
显示所有hotspot虚拟机进程
-
jstat:虚拟机统计信息监视工具
收集HotSpot各方面的运行数据,例如类装载,内存,垃圾收集等数据
jstat - [-t] [-h] [ []]
option:我们经常使用的选项有gc、gcutil
vmid:java进程id
interval:间隔时间,单位为毫秒
count:打印次数
-
jinfo:Java配置信息工具
可以实时查看和调整虚拟机的各项参数
jinfo可以用来查看正在运行的java运用程序的扩展参数,甚至支持在运行时动态地更改部分参数。
-
jmap: 内存映像工具
用于生成堆转储快照文件(heapdump文件)
jmap -heap pid:查看堆使用情况
**jmap pid **:打印的信息分别为:共享对象的起始地址、映射大小、共享对象路径的全程。
jmap -dump:format=b,file=heapdump.hprof pid:将内存使用的详细情况输出到文件
jmap -histo > jmap_xxx.txt
jmap -dump:format=b,file=dump10293.hprof 10293
sudo -u tomcat jmap -dump:live,format=b,file=/dump201612271310.dat 384
-
jhat:堆转储快照文件分析工具
用于分析生成的heapdump文件
-
jstack:Java堆栈跟踪工具
用于生成虚拟机当前时刻的线程快照(threaddump),可以用于分析死循环,死锁,长时间停顿等
主要用于生成指定进程当前时刻的线程快照,线程快照是当前java虚拟机每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致长时间等待。
jstack pid > threadPIT.txt
JVM参数说明
错误排查
网络适配器中断(错误码17002:Doc ID 353180.1)
java.sql.SQLException: Io exception: The Network Adapter could not establish the connection Error Code: 17002