输出的信息中,看得出老年代和新生代都蛮正常的,元空间也只占用了20M,直接内存看起来也是2g...
嗯?为什么MaxMetaspaceSize = 17592186044415 MB?「看起来就和没限制一样」 。
再仔细看看我们的启动参数:
-Xms4g -Xmx4g -Xmn2g -Xss1024K -XX:PermSize=256m -XX:MaxPermSize=512m -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=80
配置的是-XX:PermSize=256m -XX:MaxPermSize=512m,也就是永久代的内存空间 。「而1.8后,Hotspot虚拟机已经移除了永久代,使用了元空间代替 。」 由于我们线上使用的是JDK1.8,「所以我们对于元空间的最大容量根本就没有做限制」,-XX:PermSize=256m -XX:MaxPermSize=512m 这两个参数对于1.8就是过期的参数 。
下面的图描述了从1.7到1.8,永久代的变更:
文章插图
「那会不会是元空间内存泄露了呢?」
我选择了在本地进行测试,方便更改参数,也方便使用JVisualVM工具直观的看出内存变化 。
使用JVisualVM观察进程运行首先限制住元空间,使用参数-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m,然后在本地循环调用出问题的接口 。
得到如图:
文章插图
「可以看出,在元空间耗尽时,系统出发了Full GC,元空间内存得到回收,并且卸载了很多类 。」
然后我们将元空间限制去掉,也就是使用之前出问题的参数:
-Xms4g -Xmx4g -Xmn2g -Xss1024K -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=80 -XX:MaxDirectMemorySize=2g -XX:+UnlockDiagnosticVMOptions
得到如图:文章插图
「可以看出,元空间在不断上涨,并且已装入的类随着调用量的增加也在不断上涨,呈现正相关趋势 。」
柳暗花明又一村问题一下子明朗了起来,「随着每次接口的调用,极有可能是某个类都在不断的被创建,占用了元空间的内存」 。
观察JVM类加载情况 -verbose
?
在调试程序时,有时需要查看程序加载的类、内存回收情况、调用的本地接口等 。这时候就需要-verbose命令 。在myeclipse可以通过右键设置(如下),也可以在命令行输入java -verbose来查看 。
?
-verbose:class 查看类加载情况-verbose:gc 查看虚拟机中内存回收情况-verbose:jni 查看本地方法调用的情况
我们在本地环境,添加启动参数-verbose:class循环调用接口 。可以看到生成了无数com.alibaba.fastjson.serializer.ASMSerializer_1_WlkCustomerDto:
[Loaded com.alibaba.fastjson.serializer.ASMSerializer_1_WlkCustomerDto from file:/C:/Users/yangzhendong01/.m2/repository/com/alibaba/fastjson/1.2.71/fastjson-1.2.71.jar][Loaded com.alibaba.fastjson.serializer.ASMSerializer_1_WlkCustomerDto from file:/C:/Users/yangzhendong01/.m2/repository/com/alibaba/fastjson/1.2.71/fastjson-1.2.71.jar][Loaded com.alibaba.fastjson.serializer.ASMSerializer_1_WlkCustomerDto from file:/C:/Users/yangzhendong01/.m2/repository/com/alibaba/fastjson/1.2.71/fastjson-1.2.71.jar][Loaded com.alibaba.fastjson.serializer.ASMSerializer_1_WlkCustomerDto from file:/C:/Users/yangzhendong01/.m2/repository/com/alibaba/fastjson/1.2.71/fastjson-1.2.71.jar][Loaded com.alibaba.fastjson.serializer.ASMSerializer_1_WlkCustomerDto from file:/C:/Users/yangzhendong01/.m2/repository/com/alibaba/fastjson/1.2.71/fastjson-1.2.71.jar][Loaded com.alibaba.fastjson.serializer.ASMSerializer_1_WlkCustomerDto from file:/C:/Users/yangzhendong01/.m2/repository/com/alibaba/fastjson/1.2.71/fastjson-1.2.71.jar]
当调用了很多次,积攒了一定的类时,我们手动执行Full GC,进行类加载器的回收,我们发现大量的fastjson相关类被回收 。文章插图
「如果在回收前,使用jmap查看类加载情况,同样也可以发现大量的fastjson相关类:」
jmap -clstats 7984
文章插图
这下有了方向,「这次仔细排查代码」,查看代码逻辑里哪里用到了fastjson,发现了如下代码:
推荐阅读
- 皇菊花茶的功效与禁忌,菊花茶的禁忌与功效作用
- 监控Redis?使用Grafana的Source插件轻松搞定
- 大浪淘沙的古诗原文 浪淘沙借问长江与海水古诗
- 荀攸是荀彧的什么人 荀彧为曹操出的第一个计谋是
- 房子大了,设备多了,家里的WiFi网络该怎么优化?
- 安史之乱有多吓人 安禄山怎么死的(安禄山叛乱为什么失败)
- 在日本的中国文物 日本有哪些中国失传的古籍
- 汉朝的都城分别在哪里 汉朝首都在哪个城市
- 红楼梦中的袭人姓什么? 红楼梦袭人名字含义
- 赌书消得泼茶香当时只道是寻常中的典故出自哪位文人 赌书消得泼茶香,只道当时是寻常