问题:
报错为java.lang.OutOfMemoryError,内存溢出。根据报错并不容易定位问题,因为内存溢出的位置不一定就是报错位置。而是程序运行到报错行那一刻,产生了内存溢出。为了定位问题,我们需要工具。
image.png
问题定位
关于内存溢出,常见bug如下:
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
3.代码中存在死循环或循环产生过多重复的对象实体;
4.使用的第三方软件中的BUG;
5.启动参数内存值设定的过小;
为了定位问题,我们需要知道在jvm内存中的各个对象所占用的实际内存是多少。
jdk包内为我们提供很多的命令工具来帮助我们解决问题。如下图所示:
image.png
这些exe文件主要包括用于监视虚拟机和故障处理的工具,这些故障处理的工具被SU公司作为“礼物”附赠给jdk的使用者,并在软件的使用说明中把它们声明为“没有技术支持的实验性质的产品”,但事实上这些工具都非常稳定且强大,能在处理应用程序的性能问题、定位故障时发挥巨大作用。
1.定位进程号
首先我们通过cmd命令行转到我们的jdk的bin目录下,输入jps -l 查看当前运行的所有进程号(pid)。
image.png
2查询指定线程的内存状态
语句:jmap -heap [pid]
image.png
3查看JVM堆中对象详细占用情况
语句:jmap -heap
image.png
4生成dump文件
用jmap -heap查看并不直观,我们可以生成一个dump文件作为快照,即保存了历史内存情况,又可以用工具分析内存占用情况。
语句:jmap -dump:format=b,file=文件名 [pid]
image.png
生成位置默认就在jdk的bin目录下。
利用MAT进行分析dump文件,下面是MAT安装教程
在Eclipse help -> Eclipse Marketplace下搜索Memory:
安装后打开导出的文件:
1、打开MAT面板
2.打开导出文件
image.png
3.找到我们的dump文件就可以查看了
image.png
image.png
5.jdk内置的实时内存监控
在jdk的bin目录下,还有一个功能强大的软件,jvisualvm
打开它,并找到程序所属的线程就可以实时监控内存情况了。
image.png
问题解决
通过对dump文件分析,发现byte数组所占哦那个的内存空间过大。 image.png image.png而程序中除了正常的channel.write(),只有在read中存在new出来的byte数组。
image.png嘛,差不多了。
网友评论