赞
踩
- java.lang.StackOverflowError
栈空间溢出 ,递归调用卡死
- java.lang.OutOfMemoryError:Java heap space
堆内存溢出 , 对象过大
- java.lang.OutOfMemoryError:GC overhead limit exceeded
GC回收时间过长
过长的定义是超过98%的时间用来做GC并且回收了而不倒2%的堆内存
连续多次GC,都回收了不到2%的极端情况下才会抛出
如果不抛出,那就是GC清理的一点内存很快会被再次填满,迫使GC再次执行,这样就恶性循环,
cpu使用率一直是100%,二GC却没有任何成果
int i = 0;
List<String> list = new ArrayList<>();
try{
while(true){
list.add(String.valueOf(++i).intern());
}
}catch(Throwable e){
System.out.println("********");
e.printStackTrace();
throw e;
}
- java.lang.OutOfMemoryError:Direct buffer memory
执行内存挂了
写NIO程序经常使用ByteBuffer来读取或写入数据,这是一种基于通道(Channel)与缓存区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作,这样能在一些场景中显著提高性能,因为避免了在java堆和native堆中来回复制数据
ByteBuffer.allocate(capability) 第一种方式是分配JVM堆内存,属于GC管辖,由于需要拷贝所以速度较慢
ByteBuffer.alloctedDirect(capability)分配os本地内存,不属于GC管辖,不需要拷贝,速度较快
但如果不断分配本地内存,堆内存很少使用,那么jvm就不需要执行GC,DirectByteBuffer对象们就不会被回收,这时候堆内存充足,但本地内存可能已经使用光了,再次尝试分配本地内存救护i出现oom,程序崩溃
- java.lang.OutOfMemoryError:unable to create new native thread
解决办法
1)降低应用程序创建线程的数量,分析应用给是否针对需要这么多线程,如果不是,减到最低
2)修改linux服务器配置
- java.lang.OutOfMemoryError:Metaspace
元空间主要存放了虚拟机加载的类的信息、常量池、静态变量、即时编译后的代码
0)根据ps|top命令查看进程pid
1 )jstat -gcutil [进程id] 1000 JVM统计监测工具
2) jmap -histo [进程id] > jmap.txt 看堆内存中的对象数目如果带上live则只统计活对象
jmap -dump:format=b,file=aa.bin [进程id] dump到文件中,再用jhat分析查看
或者 MAT、JVisualVM、jprofiler 工具
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=D:\oom.hprof
1、top找到cpu高的进程
2、 找出该进程内最耗费CPU的线程 top -Hp pid
或者 - ps -mp 进程编号 -o Thread,tid,time定位到具体线程
-m :显示所有的线程
-p pid 进程使用cpu的时间
-o:该参数后是用户自定义格式
3)将该线程转为16进制
TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用
`printf` `"%x\n"` `21742`
4) jstack 21711 | grep 54ee(16进制pid)
`root@ubuntu:/``# jstack 21711 | grep 54ee``"PollIntervalRetrySchedulerThread"` `prio=10 tid=0x00007f950043e000 nid=0x54ee ``in` `Object.wait() [0x00007f94c6eda000]`
可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),找到业务代码进行排查
5)注意:
jstack [进程ID] > jstack_01(内容太多)
jstack主要用来查看某个Java进程内的线程堆栈信息。
可以看到状态不对的线程,以及是否有死锁
JProfiler 是由 ej-technologies 公司开发的一款 Java 应用性能诊断工具。它聚焦于四个重要主题上。
方法调用 - 对方法调用的分析可以帮助您了解应用程序正在做什么,并找到提高其性能的方法。
内存分配 - 通过分析堆上对象、引用链和垃圾收集能帮您修复内存泄漏问题,优化内存使用。
线程和锁 - JProfiler 提供多种针对线程和锁的分析视图助您发现多线程问题。
高级子系统 - 许多性能问题都发生在更高的语义级别上。例如,对于JDBC调用,您可能希望找出执行最慢的 SQL 语句。JProfiler 支持对这些子系统进行集成分析。
2.1 本地监控或者分析dump
JVisualvm 是 JDK 内置的可视化性能诊断工具,它通过 JMX、jstatd、Attach API 等方式获取目标 JVM 的分析数据,包括 CPU 使用率、内存使用量、线程堆栈信息等。
直观地展示 Java 堆中各对象的数量和大小;
各 Java 方法的调用次数和执行时间。
分析dump文件,比较两个dump文件内存对象差异
https://mp.weixin.qq.com/s/Q1NJ5bQmu8c6y0g9XXWwrwJProfiler
2.2监控远程JVM
1)概述:该JVM进程的主类,参数和详细的jvm参数等
2)监视:包含CPU,堆(内存),类的加载和启动的线程等信息
3)线程:线程相关的信息
4)抽样:可对CPU、内存进行抽样
5)Visual GC
查看CPU
vmstat -n 2 3 第一个参数是采样的时间间隔数单位s,第二个参数是采样的次数
- procs
r:运行和等待CPU时间片的进程数,原则上1核CPu的运行队列不要超过2,真个系统的运行队列不能超过总核数的2倍,否则表示系统压力过大
b:等待资源的进程数,比如正在等待磁盘I/O,网络I/O等
- cpu
us:用户进程消耗cpu时间百分比,us高,用户进程消耗cpu时间多,如果长期大于50%,优化程序
sy:内核进程消耗的cpu时间百分比
us+sy:参考值为80%,如果大于80,说明可能存在cpu不足
id:处于空闲的cpu百分比
wa:系统等待IO的cpu时间百分比
st:来自于一个虚拟机偷取的cpu时间的百分比
查看额外
查看内存 free -m free -g
pidstat -p 进程编号 -r 采样间隔秒数
查看磁盘剩余空间 df -h
iostat -hdk 2 3
- rkB/s每秒读取数据kb;
- wkB/s每秒读写数据量kb
- svctm I/O请求的平均服务时间,单位毫秒;
- await I/O请求的平均等待时间,单位毫秒;值越小,性能越好;
- ==util== 一秒中又百分几的时间用于I/O操作,接近100%时,表示磁盘带宽跑满,需要优化程序或加磁盘
- rkB/s,wkB/s根据系统该应用不同回有不同的值,担忧规律遵循:长期、超大数据读写,肯定不正常,需要优化程序读取。
- svctm的值与await的值很接近,表示几乎没有I/O等待,磁盘性能好,如果await的值远高于svctm的值,则表示I/O队列等待太长,需要优化程序或更换更快磁盘
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。