内存溢出分析定位

摘要:
内存溢出:堆内存溢出堆内存中存在大量对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,就会出现内存溢出OutOfMemory:Javaheapspace永久代溢出--(解决方案:加大永久代内存)类的一些信息,如类名、访问修饰符、字段描述、方法描述等,所占空间大于永久代最大值,就会出现OutOfMemoryError:PermGenspace内存溢出的检测方法1、Jdk/bin目录下有

内存溢出:

  • 堆内存溢出

堆内存中存在大量对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,
就会出现内存溢出OutOfMemory:Java heap space

  • 永久代溢出 -- (解决方案:加大永久代内存)

类的一些信息,如类名、访问修饰符、字段描述、方法描述等,所占空间大于永久代最大
值,就会出现OutOfMemoryError:PermGen space

内存溢出的检测方法

1、Jdk/bin目录下有很多检测工具
  • 图形界面:
    – Jconsole
    – Jvisualvm(也可以监控线程)
  • 命令行工具
    –Jstat –gcutil pid 1000 100 查看GC情况
    -Jmap –histo pid | head -20 查看当前jvm中占用内存最大的20个类
    -Jmap –heap pid

FullGC频率:建议单次FullGC时间<200ms,超出则存在优化空间

2、现象
2.1 垃圾回收和CPU使用率

image

1、两条曲线的走势完美吻合,每一次GC,CPU使用率都会升高,请求响应时间变长
2、有时候CPU使用率波动特别大,有可能正在进行 GC
3、响应时间波动特别大、TPS波动也特别大,系统有可能在进行 GC,需要排查

2.2 内存泄漏和TPS

image

1、TPS开始有波动,然后波动越来越大,最后陡降至0

内存溢出实战

内存溢出分析定位第3张

怎么排查:

  • 1、观察现象:tps先是出现大幅波动,后慢慢降低。甚至将为0,响应时间随之波动,慢慢升高
  • 2、通过 jstat -gcutil pid 1000 100命令可以观察到 Jvm中的Old区不断增加,FGC(FullGC)非常频繁,对应FGCT(FullGC需要的时间)消耗的时间也不短增加
  • 3、通过 jconsole/jvisualvm 可以看到,堆内存曲线不断上升,接近上线时,变成一条直线,就算压测结束很久后,内存仍然降不下来
  • 3、日志报错 java.lang.OutOfMemoryError:Java heap space
  • 4、通过 Jmap –histo pid | head -20 查看当前jvm堆内存中实例数和占用内存最多的前20个对象或类
  • 5、也可以通过jvisualvm,进行远程堆dump,然后把dump文件下载下来,用jvisualvm打开进行分析,可以看到更直观的jvm中对象的信息

查看Jvm运行状态的命令

监控jvm的GC情况
jstat -gcutil pid 1000 100

查看jvm配置信息
jmap -heap pid:可以看到java进程的堆的配置信息,各区的空间大小和配置信息

查看jvm中类和对象的占用情况
jmap -histo 5279 | head -20:查看jvm中各个类的实例数、占用内存数量以及类的全名

堆文件dump
jmap -dump:format=b,file=m.hdump 17777:对堆内存进行dump,以文件的形式进行保存下来,可以用jvisualvm等工具对文件进行分析

内存泄露应用场景

在什么样的场景下监控内存泄露问题?

  • 1、在试压阶段,或任意场景都可以考虑通过jvisualvm和jstat监控jvm的情况
  • 2、在稳定性场景中,一定要关注Jvm内存使用的情况,在长时间的压测下,最容易看出内存泄露的问题

JVM常见参数

-Xms2048m:初始堆大小,建议<物理内存的1/4,默认值为物理内存的1/64
-Xmx2048m:最大堆大小,建议与-Xms保持一致,默认值为物理内存的1/4
-Xmn512m:新生代大小,建议不超过堆内存的1/2
-Xss256k,线程堆栈大小,建议512-1024k
-XX:PermSize=256m:永久代初始值,默认值为物理内存的1/64
-XX:MaxPermSize=256m:永久代最大值,默认值为物理内存的1/4
-XX:SurvivorRatio=8:年轻带中Eden区和Survivor区的比例,默认为8:1,即Eden(8),From
Space(1),ToSpace(1)
-XX:MaxTenuringThreshold=15:晋升到老年代的对象年龄,每个对象坚持过一次MinorGC后对象年龄+1,默认值是15,年龄超过15进入到老年代,该参数在串行GC时有效-
XX:PretenureSizeThreshold=3145728:单位字节,只对Serial和ParNew两款收集器有效,新生代采用Parallel Scavenge GC时无效,大于这个值的对象直接在老年代进行分配

CMS相关参数

-XX:+UseConcMarkSweepGC:默认关闭,ParNew+CMS+Serial Old,当CMS收集器出现
ConcurrentModeFailure错误(Jvm预留空间不足以容纳程序使用),采用后备收集器Serial Old
-XX:CMSInitiatingOccupancyFraction=80:CMS收集器在老年代空间被使用多少时触发FullGC,默认为92
-XX:+UseCMSCompactAtFullCollection:CMS收集器在FullGC时开启内存碎片的压缩,默认关闭
-XX:CMSFullGCsBeforeCompaction=8:执行多少次不压缩FullGC后,进行一次压缩,默认是0(代表每次FullGC都进行压缩)
-XX:+UseCMSInitiatingOccupancyOnly:使用手动定义初始化定义开始,禁止hostspot自行触发CMS GC
-XX:ParallelGCThreads=8:并行收集器的线程数,此值最好配置与处理器数目相等 同样适用于CMS

日志参数:

-XX:+HeapDumpOnOutOfMemoryError:当发生内存溢出时,进行堆内存dump-XX:+PrintGCDetails:打印GC的详细信息

企业实际测试环境配置

-server -Xms1028m -Xmx1028m -XX:PermSize=256m -XX:MaxPermSize=256m -Xmn512m
-XX:MaxDirectMemorySize=1g -XX:SurvivorRatio=10 -XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection -XX:CMSMaxAbortablePrecleanTime=5000
-XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=80
-XX:+UseCMSInitiatingOccupancyOnly -XX:ParallelGCThreads=8
-Xloggc:/home/admin/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/home/admin/logs/java.hprof

免责声明:文章转载自《内存溢出分析定位》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java实现bt文件下载、制作、解析、磁力链接利用js获取图片尺寸与图片大小(高度与宽度)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

MAT工具定位分析Java堆内存泄漏问题方法

一、MAT概述与安装 MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题。该工具提供了两种使用方式,一种是插件版,可以安装到Eclipse使用,另一种是独立版,可以直接解压使用。 我把独立版MAT安装包放到了网盘上,方便直接下载———— 链接:https://pan.baidu.com/s/1...

从jvm的角度来看java的多线程

最近在学习jvm,发现随着对虚拟机底层的了解,对java的多线程也有了全新的认识,原来一个小小的synchronized关键字里别有洞天。决定把自己关于java多线程的所学整理成一篇文章,从最基础的为什么使用多线程,一直深入讲解到jvm底层的锁实现。 多线程的目的 为什么要使用多线程?可以简单的分两个方面来说: 在多个cpu核心下,多线程的好处是显而易见...

Java内存溢出的详细解决方案 转载

一、内存溢出类型 1、java.lang.OutOfMemoryError: PermGen space JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它 和堆不同,运行期内GC不会释放空间。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好...

JVM 入门指南

一、什么是JVM?JVM: JVM是Java Virtual Machine的缩写,中文翻译为Java虚拟机。JVM 可以看作一台抽象的计算机,如同真实的计算机一样,它有自己的指令集和各种运行时区域。 JVM 是整个 Java 平台的基石,是 Java 技术用以实现硬件无关与操作系统无关的关键部分,是 Java 语言生成的极小体积的编译代码的运行平台,...

JVM:查看java内存情况命令

  jmap (linux下特有,也是很常用的一个命令)   观察运行中的jvm物理内存的占用情况。   参数如下:   -heap :打印jvm heap的情况   -histo: 打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。   -histo:live : 同上,但是只答应存活对象的情况   -permstat: 打印pe...

JVM三种类型参数详解

一、概述   JVM参数调优是程序员必备的技能,JVM的参数主要分为三种类型:1、标准型:稳定,比如java -version   2、X:相对变化较少的  3、XX:JVM调优的主要部分 二、JVM调优参数   XX:型参数主要分为如下两种   2.1 Boolean类型的   a、使用方法是:-XX:[+/-] name     开启使用+:比如开启G...