Java 内存泄露查看


内存泄露:该释放的内存没有释放。
内存溢出:无法申请内存。
内存泄露到可泄露上限就会内存溢出。内存包括物理内存和虚拟内存。

以产生的方式来分类,内存泄漏可以分为四类:
常发性内存泄漏:发生内存泄漏的代码会被多次执行到,每次被执行时都会导致一块内存泄漏。
偶发性内存泄漏:发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。
一次性内存泄漏:发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏。
隐式内存泄漏:程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。

排除内存泄露的工具:
(1)jconsole
(2)jvisualvm
jconsole和jvisualvm存在于JDK的bin中。
jvisualvm有两个分发渠道,Github和JDK。Oracle JDK 9开始,jvisualvm已经转移到graalvm(一个创新的,高性能的多语言VM性能监控器)。

IDEA 插件:
JVM Debugger Memory View:2018社区版及2019专业版等版本不支持。
JProfiler:需结合JProfiler工具(需购买,可试用)。

jconsole和jvisualvm可以查看程序的线程。

查看程序的所有类的cmd方式:
java -verbose:class 程序名
程序名(包括模块源码根目录开始的包)查看:
jps

报:错误: 找不到或无法加载主类
确认一下:
(1)系统环境变量中的JDK版本是不是等于或高于程序启动使用的JDK版本,如果不是:
cd到启动类class所在模块目录,执行:
# 比如程序启动使用的JDK为:C:\Program Files\Java\jdk11.0.5-win_x64
set JAVA_HOME=C:\Program Files\Java\jdk11.0.5-win_x64;
set CLASSPATH=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOMe%\lib\tools.jar;
set Path=%JAVA_HOME%\bin;
(2)cd到启动类class所在模块目录再执行java -verbose:class 程序名

报:原因: java.lang.NoClassDefFoundError: javafx/application/Application
暂时想法是打包后执行,但如果频繁改动源码,并不合适。

查看程序的所有类的jvisualvm方式(推荐):
抽样器中可查看加载的所有类、类个数、实例个数,并实时刷新,底部可模糊查找类,方便定位项目模块中的类。

监视中点击堆dump可以生成瞬时的类和实例情况,类视图(类的实例数量、内存大小等)中下方有过滤框,过滤框左侧图标可选择过滤方式。类右键可以查看实例的变量、属性、方法、引用,实例右键可以查看最近回收的引用位置。
可参考:
浏览Heap Dump
Java性能调优:利用VisualVM进行性能分析

报:无法为以下项生成堆 或者 一直处于正在加载堆dump 或者 无法对比堆dump:查看一下系统盘是否有充足空间,jvisualvm是否是以管理员身份运行的(程序或IDE也需以管理员身份运行,否则Java进程文件没有权限写入系统盘)。

发布了388 篇原创文章 · 获赞 105 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/haoranhaoshi/article/details/104993047