StackOverflowError 和 OutOfMemoryError 是 JVM 里的两种 Error。每个运行时区域——程序计数器
、Java 虚拟机栈、本地方法栈、Java 堆、方法区、直接内存发生 Error 的原因和错误信息是不同的。
不是所有的 StackOverflowError 和 OutOfMemoryError 都需要调整参数,要做到正确分析、合理调整
常见异常说明
java.lang.OutOfMemoryError:java heap space
排查思路
检查 Java 虛拟机的堆参数设置,与机器的内存对比,看看是否还有向上调整的空间。再从代码上检查是否存在某些对象生命周期过长、持有状态时间过长、存储结构设计不合理等情况,尽量减少程序运行期的内存消耗。
参数配置
-Xmx 最大堆大小 默认物理内存的1/64
-Xms 初始堆大小 默认物理内存的1/4(<1GB)
HotSpot 虚拟机栈=虚拟机栈 + 本地方法栈
java.lang.StackOverflowError
java.lang.OutOfMemoryError
-Xss 每个线程堆栈的大小。一般情况下256K是足够了。影响此进程中并发线程数大小等。
JDK1.7以前的错误信息
java.lang.OutOfMemoryError: PermGen space
<= JDK1.6
-XX:PermSize
-XX:MaxPermSize
>= JDK1.8
-XX:MetaspaceSize
-XX:MaxMetaspaceSize 元空间最大值,默认是-1,即不限制,或者说只受限于本地内存大小。
java.lang.OutOfMemoryError
-XX:MaxDirectMemorySize 默认与Java堆最大值(由-Xmx指定)一致
JDK 自带的分析工具
jps JVM Process Status Tool 显示指定系统内所有的HotSpot虚拟机进程
jinfo Configuration Info for Java 显示虚拟机配置信息
jmap JVM Memory Map 生成虚拟机的内存转储快照,生成heapdump文件
jhat JVM Heap Dump Browser 用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户在浏览器上查看分析结果
jstat JVM Statistics Monitoring Tool 用于收集Hotspot虚拟机各方面的运行数据
jstack JVM Stack Trace 显示虚拟机的线程快照
可以显示本地或者远程虛拟机进程中的类加载、内存、垃圾收集、即时编译等运行时数据,在没有 GUI 图形界面、只提供了纯文本控制台环境的服务器上,是运行期定位虚拟机性能问题的常用工具。
-class
监视类加载、卸载数量、总空间以及类装载所耗费的时间
-gc
监视Java堆状况,包括Eden区、2个Survivor区、老年代、永久代等的容量,已用空间,垃圾收集时间合计等信息
-gccapacity
监视内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间
-gcutil
监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
-gccause
与-gcutil功能--样,但是会额外输出导致上一次垃圾收集产生的原因
-gcnew
监视新生代垃圾收集状况
-gcnewcapacity
监视内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间
-gcold
监视老年代垃圾收集状况
-gcoldcapacity
监视内容与-gcold基本相同,输出主要关注使用到的最大、最小空间
-gcpermcapacity
输出永久代使用到的最大、最小空间
-compiler
输出即时编译器编译过的方法、耗时等信息
-printcompilation
输出已经被即时编译的方法
可以生成虚拟机当前时刻的线程快照 (-般称为 threaddump 或者 javacore 文件)。线程快照就是当前虚拟机内每 - 条线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的常见原因。线程出现停顿时通过 jstack 来查看各个线程的调用堆栈,就可以获知没有响应的线程到底在后台做些什么事情,或者等待着什么资源。
jstack -l 进程ID
除堆栈外显示关于锁的附加信息
扫一扫,关注我