大家好,可爱的我,最帅的我再次登场,刚过完年,首先祝大家新年happy!
刚回到这个可爱的大家庭里,就受到了老天无限制的'照顾','怜惜',去年做的农发行项目(是个springcloud项目),竟然发生了一个Memory Out异常:java heap space ,堆内存溢出了,堆内存意味着什么这里就不解释了,说白了就是过多的实例化对象.看一下内存溢出的异常图吧
我曹,尽然没一行报错是我们团队写的,当时就一脸懵逼,但我这人就喜欢迎难而上,恰巧前段时间看了看<<02.深入理解Java虚拟机:JVM高级特性与最佳实践>>,对jvm有一点点的了解,好,废话不说,直接上jvm调试神器
神器是jdk自带的 ,bin目录下,其他的就自己了解去吧
首先大致说一下项目其他不用管,gate是网关(zuul),在做一个**文件上传功能**时,爆出的异常,所有项目的内存大小都是xms256m xmx512m(个人不建议初始内存和最大内存不一致,会导致没必要的开辟和释放,影响性能,通过看神器jvm内存就可以看出!)
看到这,有些人可能直接会说xms和xmx都太小,第一个我就想到先将内存调到512m-1024m,这时,再次上传300+m的文件还是爆了异常
不说废话,直接开始神器调试,本地就是你运行的几个项目,也可以说是几个主线程,由于异常是在gate中爆出,所以 现在需要双击gate,也就是pid 28616,
打开之后会出现这样一个界面,概述里可以看到jvm的明细等等,这里就直接跳过,到监视窗口,看堆内存,都是汉字,不用解释了吧.
通过这里可以看到最大内存536m,已使用292m,这是设置过jvm内存大小,这样上传会直接报异常,看不到效果,所以先将内存大小别设置,让自由生长.下图就是没进行设置过的
发完文件上传请求(文件是300+m ),瞬间增加三四倍,对照上图观察
此时,就可以排查问题所在的地方,首先点击 [堆 dump 快照]按钮,会出现下面的页面
切换到类选项卡对右边的大小进行排序,尽然发现byte[]占用了将近700m,而分配的内存大小只有500m最大,
此时点击byte[]右键,在实例视图中显示
此时,点击右边的this,在随意点击左边的实例,点击的同时查看引用框,
引用框的内容一目了然,是request中存放了大值数据,而且是form表单中表单体中,此时问题找到,上传文件是内存溢出是由于请求体存放数据过大导致,并非泄漏等等问题.
最后,给出解决方案
1.搭建文件服务器(推荐方案)
2.内存调到3g (由于已上传文件内存最大可到1.7g,所以为了给留有足够的空间,就给3g)
可以关注下博主的公众号,实时推送解决方案!