四、内存溢出排查一般来说内存溢出主要分为以下几类:
堆溢出(java.lang.OutOfMemoryError: Java heap space)栈深度不够( java.lang.StackOverflowError)栈线程数不够(java.lang.OutOfMemoryError: unable to create new native thread)元空间溢出(java.lang.OutOfMemoryError: Metaspace)1、元空间溢出(java.lang.OutOfMemoryError: Metaspace)Metaspace元空间主要是存储类的元数据信息 , 各种类描述信息 , 比如类名、属性、方法、访问限制等 , 按照一定的结构存储在Metaspace里 。一般来说 , 元空间大小是固定不变的 。在出现溢出后 , 首先通过命令或监控工具(如下图)查看元空间大小 , 再检查是否-XX:MaxMetaspaceSize配置太小导致 。
文章插图
文章插图
文章插图
如果发现元空间大小是持续上涨的 , 则需要检查代码是否存在大量的反射类加载、动态代理生成的类加载等导致 。可以通过-XX:+TraceClassLoading -XX:+TraceClassUnloading记录下类的加载和卸载情况 , 反推具体问题代码 。
文章插图
2、栈深度不够(java.lang.StackOverflowError)引发StackOverFlowError的常见原因有:
- 无限循环递归调用
- 同一时间执行大量方法 , 资源耗尽
- 方法中声明大量局部变量
- 其它消耗栈资源的方法
- xss配置太小导致
/** * VM Args: -Xss128k */public class JavaStackSOF {private int stackLength = 1;public void stackLeak() {stackLength++;stackLeak();}public static void main(String[] args) {JavaStackSOF oom = new JavaStackSOF();try{oom.stackLeak();}catch(Throwable e) {System.out.println("stack length:" + oom.stackLength);throw e;}}}
stack length:2101Exception in thread "main" java.lang.StackOverflowErrorat com.sandy.jvm.chapter02.JavaStackSOF.stackLeak(JavaStackSOF.java:13)at com.sandy.jvm.chapter02.JavaStackSOF.stackLeak(JavaStackSOF.java:14)at com.sandy.jvm.chapter02.JavaStackSOF.stackLeak(JavaStackSOF.java:14)
3、栈线程数不够(java.lang.OutOfMemoryError: unable to create new native thread)这类错误目前在生成系统只遇到过一次 , 原因是:linux系统中非root用户默认创建线程数最多是1024 。解决办法是修改文件:/etc/security/limits.d/90-nproc.conf还有一种情况是-xss配置太大 , 那么操作系统可创建的最大线程数太小导致 , 一般除非误操作是不会出现此问题的 。4、堆溢出(java.lang.OutOfMemoryError: Java heap space)堆溢出是常见也是最复杂的一种情况 。导致堆溢出可能的情况有:
- 堆内存配置太小
- 超出预期的访问量:访问量飙升
- 超出预期的数据量:系统中是否存在一次性提取大量数据到内存的代码
- 内存泄漏
一、堆dump文件获取1、通过参数配置自动获取dump文件(推荐)2、jmap -dump:format=b,file=filename.hprof pid二、MAT工具分析1、分析大对象、堆中存储信息、可能存在的内存泄漏地方 , 便于定位问题位置五、JVM监控常用的监控工具或命令有:jstack、jstat、jConsole、jvisualvm 。监控指标主要是各内存区域大小是否合理、fullGC频率及耗时、youngGC耗时、线程数等 。
1、jstackjstack主要用于打印线程堆栈信息 , 帮助问题的定位 。一般配合top -Hp PID使用 。
通过top命令发现某个java服务占用1234%的CPU , 如图:
经验总结扩展阅读
- java中GC的日志认识详解
- Learning Records JavaScript进阶
- 31 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android系统中Flutter应用程序的包
- iphone13系列电池容量_iphone13系列续航对比
- 红魔手机6SPro多少钱_红魔手机6SPro价格多少
- 西瓜为什么叫西瓜呢
- 《上传那些事儿之Nest与Koa》——文件格式怎么了!
- 4 Java多线程:ThreadLocal
- C++算法之旅、02 从木棒切割问题领悟二分法精髓
- 特别特别透彻的签名 有道理的霸气签名