温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

JAVA中怎么排查内存泄漏

发布时间:2021-06-22 17:51:36 来源:亿速云 阅读:169 作者:Leah 栏目:编程语言

这篇文章将为大家详细讲解有关JAVA中怎么排查内存泄漏,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

内存泄漏

内存泄漏(Memory Leak)是指程序中一个对象或变量无法回收,一直保存在内存中。这样的对象或变量一直累计,最终导致内存溢出(Out Of Memory)。

内存泄漏原因

内存泄漏大概有以下几个原因

1.静态集合存放对象

长周期对象持有了短周期的对象的引用,就可能导致内存泄漏。如果集合是静态的,那么该集合的生命周期就和程序的生命周期一致。且对象存放在静态集合中,所以在整个程序的生命周期内,对象都无法被释放,最终导致内存泄漏。

2.连接未关闭

数据库连接,网络连接,IO连接等生成连接后,如果没有调用close方法,则会造成相关的对象无法被回收,导致内存泄漏。

3.单例对象

单例对象的生命周期和程序的生命周期也是一致的,所以如果单例对象引用了一个外部对象,那么这个外部对象在程序结束前也是无法被释放的。存在内存泄漏的风险。

4.改变对象HASH值

如果一个对象被存入HashSet集合,再修改对象参与Hash值计算的属性,那么对象的Hash值就会改变。由于对象存入HashSet集合时存放的位置是根据旧Hash值获得的,那么当Hash变动后,已经找不回原来的位置,这就导致这个对象无法在HashSet被搜索到,也无法被删除。由于一直存在于HashSet,那么除非HashSet被释放,否则该对象将一直被HashSet引用,从而无法被释放,造成内存泄漏。

5.内部类持有外部类引用

如果一个内部类调用了一个外部类的方法,并且将内部类作为参数传递过去。那么如果外部类不释放这个内部类,这个内部类就无法释放,就可能造成内存泄漏。

排查步骤

1.通过jps命令找出正在执行的虚拟机进程,获取进程的在虚拟机中的唯一ID,命令格式如下:

Jps [options] [hostid]

例如 jps -l,结果如下:

JAVA中怎么排查内存泄漏

options的参数如下:

-q

 不输出类名、Jar名和传入main方法的参数

-m

输出传入main方法的参数

-l

输出main类或Jar的权限名

-v

输出传入JVM的参数

hostid可以用来查看其他服务器上虚拟器的进程,默认是本机

2.获取唯一ID,可以使用jstat监视进程状态,命令格式如下:

Jstat [option vmid [interval[s|ms] [count]]]

例如 jstat -gc 12116 1000  4

每隔1000毫秒查询某个进程的已使用空间占总空间百分比,总共查4次,结果如下

JAVA中怎么排查内存泄漏

S0C

生存区0容量

S1C

生存区1容量

S0U

生存区0使用量

S1U

生存区1使用量

EC

Eden区容量

EU

Eden区使用量

OC

老年代容量

OU

老年代使用量

MC

方法区容量

MU

方法区使用量

CCSC

压缩类空间容量

CCSU

压缩类空间使用量

YGC

年轻代GC次数

YGCT

年轻代GC耗时

FGC

FULL GC 次数

FGCT

FULL GC 耗时

GCT

GC总耗时

option的参数如下

-class

显示加载class的数量,及所占空间等信息

-compiler

显示VM实时编译的数量等信息

-gc

可以显示gc的信息,查看gc的次数,及时间

-gccapacity

可以显示VM内存中三代(young,old,perm)对象的使用和占用大小

-gcutil

统计gc信息

-gcnew

年轻代对象的信息

-gcnewcapacity

年轻代对象的信息及占用量

-gcold

old代对象的信息

-gcoldcapacity

old代对象的信息及占用量

-gcpermcapacity

perm对象的信息及占用量

-printcompilation

当前VM执行的信息

3.可以使用jmap分析堆内存使用情况,命令格式如下:

jmap [option] pid

例如:jmap -histo:live 6088,结果如下

JAVA中怎么排查内存泄漏

没有参数打印进程的类加载器和类加载器加载的持久代对象

option的参数如下

-heap

查看进程堆内存使用情况,包括使用的GC算法、堆参数配置和各代中堆内存的使用情况

-histo

查看堆内存中的对象数目、大小统计

-histo:live

查看堆内存中活的对象数目、大小统计,并进行一次GC

-dump:format=b,file=dumpFileName

用jmap把进程内存使用情况dump到文件中

通过检查类的占用情况可以分析是哪个类出现了内存泄漏,实在不行,也可以通过dump命令生成dump文件进一步分析。

例如

jmap -dump:format=b,file=20210512.dump 6088

然后使用jvisualvm工具分析dump文件

关于JAVA中怎么排查内存泄漏就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI