万隆的笔记 万隆的笔记
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
  • 大纲

  • 走近Java

  • 内存与垃圾回收

  • 字节码与类加载

  • 性能监控与调优

  • 监控与性能调优案例

    • JVM监控与性能调优案例概述
    • Tomcat堆溢出分析
    • 堆溢出
      • 报错信息
      • 案例模拟
      • 分析解决
    • 方法区溢出
    • GC overhead limit exceeded
    • 线程溢出
    • 调整堆大小提高服务的吞吐量
    • JVM优化之JIT优化
    • 合理配置堆内存
    • CPU占用很高排查方案
    • G1并发执行的线程数对性能的影响
    • 调整垃圾回收器提高服务的吞吐量
    • 日均百万级订单交易系统如何设置JVM参数
    • 内存泄漏与内存溢出
  • Java虚拟机
  • 监控与性能调优案例
2022-03-17
目录

堆溢出

# 堆溢出

# 报错信息

报错信息:java.lang.OutOfMemoryError: Java heap space

# 案例模拟

一个Spring Boot应用,主要如下,详见案例代码。请求 http://localhost:8080/add

/**
 * 案例1:模拟线上环境OOM
 */
@RequestMapping("/add")
public void addObject(){
    System.err.println("add"+peopleSevice);
    ArrayList<People> people = new ArrayList<>();
    while (true){
        people.add(new People());
    }
}

JVM参数配置:

-Xms80M 
-Xmx80M
-XX:MetaspaceSize=64m
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:log/gc-oomHeap.log
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=heap/heapdump.hprof

运行结果:

java.lang.OutOfMemoryError: Java heap space 
  at java.util.Arrays.copyOf(Arrays.java:3210) ~[na:1.8.0_131]
  at java.util.Arrays.copyOf(Arrays.java:3181) ~[na:1.8.0_131]
  at java.util.ArrayList.grow(ArrayList.java:261) ~[na:1.8.0_131]
  at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235) ~[na:1.8.0_131]
  at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227) ~[na:1.8.0_131]

关于如何获取dump文件详见:获取dump文件。注意,于我们当前设置的内存比较小,所以该文件比较小,但是正常在线上环境,该文件是比较大的,通常是以G为单位。

# 分析解决

VisualVM分析dump文件:

oom_case1_1

MAT分析dump文件:

oom_case1_2

GCEasy分析log文件:

oom_case1_3

原因:

  1. 代码中可能存在大对象分配
  2. 可能存在内存泄漏,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。

解决方案:

  1. 检查是否存在大对象的分配,最有可能的是大数组分配
  2. 通过jmap命令,把堆内存dump下来,使用MAT等工具分析一下,检查是否存在内存泄漏的问题
  3. 如果没有找到明显的内存泄漏,使用 -Xmx 加大堆内存
  4. 还有一点容易被忽略,检查是否有大量的自定义的 Finalizable 对象,也有可能是框架内部提供的,考虑其存在的必要性
#JVM监控与性能调优案例
上次更新: 5/28/2023, 10:57:53 PM
方法区溢出

方法区溢出→

最近更新
01
2025
01-15
02
Elasticsearch面试题
07-17
03
Elasticsearch进阶
07-16
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式