java内存溢出初步排查

发布时间:2023年12月26日

java内存模型

java内存空间主要包括以下几个部分:方法区、堆内存、虚拟机栈、本地方法栈

  • 方法区:主要存放已被加载的类信息,常量,静态变量等。
  • 堆内存:Java堆是JVM所管理的最大一块内存空间,几乎所有的对象实例都会在这里分配内存
  • 虚拟机栈:每个线程私有。生命周期与线程相同,主要用于存储局部变量表,操作数栈,动态链接,方法出口等
  • 本地方法栈:与虚拟机栈类似,主要为JVM使用到的Native方法服务

java内存溢出的根源

在以上四个区域中,内存溢出主要发生在堆内存和方法区中。其中,堆内存溢出最为常见。它主要由以下两种原因引起:

  • 内存泄露:程序中某个部分的内存未能被释放掉,这块内存随着时间的推移,会逐渐积累,最终导致内存溢出
  • 当程序需要申请的内存超过JVM堆的最大限制时,会抛出内存溢出错误

排查内存溢出思路

  • 检查代码:找出可能导致内存泄露的代码段,如未关闭的资源,长生命周期对象持有短生命周期对象的引用等
  • 使用内存分析工具:内存分析工具(如JProfiler, MAT, VisualVM等)可以对Java堆进行深入的分析,找出内存使用的热点
  • 生成堆转储文件:当发生内存溢出时,可以生成堆转储文件进行分析,这可以通过-XX:+HeapDumpOnOutOfMemoryError和-XX:HeapDumpPath参数配置JVM实现。

常用命令

查看内存使用情况和gc情况

/opt/infosec/NetSeal/jdk1.8.0_121/bin/jstat -gc -h1 pid 1s

在这里插入图片描述
其对应的指标含义如下:

  • S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
  • S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
  • S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
  • S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
  • EC 年轻代中Eden(伊甸园)的容量 (字节)
  • EU 年轻代中Eden(伊甸园)目前已使用空间 (字节)
  • OC Old代的容量 (字节)
  • OU Old代目前已使用空间 (字节)
  • MC 方法区大小
  • MU 方法区目前已使用空间 (字节)
  • CCSC 压缩类空间大小
  • CCSU 压缩类空间已使用大小
  • YGC 从应用程序启动到采样时年轻代中gc次数
  • YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
  • FGC 从应用程序启动到采样时old代(全gc)gc次数
  • FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
  • GCT 从应用程序启动到采样时gc用的总时间(s)

查看jvm信息 主要是最大内存

/opt/infosec/NetSeal/jdk1.8.0_121/bin/jinfo -flags 968687

打印线程信息

/opt/infosec/NetSeal/jdk1.8.0_121/bin/jcmd <pid> Thread.print
gc

手动释放gc

/opt/infosec/NetSeal/jdk1.8.0_121/bin/jcmd <pid> GC.run

在这里插入图片描述
执行完之后,可以去查询此时的内存
在这里插入图片描述
当OU和OC 相差很多时,说明手动执行GC成功,不存在内存泄露,不存在未被释放的对象,当OU和OC相差微小时,即没有可用内存,会发生内存溢出

文章来源:https://blog.csdn.net/qq_42383970/article/details/135223139
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。