【JVM】问题排查
jetty的调用场景是:为了支持servlet规范中的注解方式(使得不再需要在web.xml文件中进行servlet的部署描述,简化开发流程),jetty在启动时会扫描class、lib包,将使用注解方式声明的servlet、listener注册到jetty容器,在扫描jar包的时候调用了inflate,分配了大量的内存,此时通过关键词搜索到memory leak while scanning annotations,这篇文章给出了两种解决方法,一种是评论处所说,禁用缓存(说是jdk1.8的bug):
here’s a link to the java bugs database issue: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8156014
i’d like to be able to comment on it, but i can’t seem to find a link to allow me to do that.
the comments i’d like to add are:
the problem is still reproduceable as of jdk8u112
the problem seems to be fixed in jdk9: i tested jdk9ea+149 and couldn’t reproduce
i’ve tried some workarounds for jdk8: it seems the serviceloader impl uses the jarurlconnection caching, so it may be of some benefit to try to disable url caching (although not sure of the effects on performance).
try creating an xml file (eg called “caches.xml”) with the following contents:
<configure id="server" class="org.eclipse.jetty.server.server">
<set class="org.eclipse.jetty.util.resource.resource" name="defaultusecaches">false</set>
<new class="java.io.file">
<arg>
<systemproperty name="java.io.tmpdir"/>
</arg>
<call name="touri">
<call id="url" name="tourl">
<call name="openconnection">
<set name="defaultusecaches">false</set>
</call>
</call>
</call>
</new>
</configure>
尝试之后,java进程占用的物理内存由6.5g降到了5.9g,有一定的效果,但是我们估算的java进程应该占4.5g左右,还有1.4g内存被谁占用了呢?
再尝试另外一种方法:
we were investigating a jetty application that used much more memory than it was supposed to do (near a gb more than the max heap size plus the max metaspace size). we found out that the extra memory was native memory, being allocated using malloc via some library (we don’t have native code in our app). then we used jemalloc ( http://www.canonware.com/jemalloc/) to find out which class was doing this allocation and we found out that it was java.util.zip.inflater. via jstack we were able to find calls to the library and the main caller was jetty, while in the process of looking for annotations. we disable annotations for the application and the memory usage went back to normal.
既然jetty调用是因为扫描jar包中的注解,我们应用中没有通过注解声明的servlet、listener,是不是可以不需要扫描这一步,故而在jetty.xml中将注解扫描的方式去掉:
<!-- <item>org.eclipse.jetty.annotations.annotationconfiguration</item> -->
<!-- item>com.xxx.boot.rjrannotationconfiguration</item> -->
再重启应用,发现内存使用由6.5g降到了3.9g,并且应用运行稳定后不再占用swap,
出处:
http://www.longtask.net/2018/11/15/swap-used-full/#top
上一篇: Redisson实现分布式锁(二)
下一篇: Java学习笔记01
推荐阅读
-
解决Vue调用springboot接口403跨域问题
-
A5营销:网站“抓取异常”问题的解决方案
-
Android开发中计算器的sin、cos及tan值计算问题分析
-
Android 中出现java.net.BindException: bind failed: EADDRINUSE 问题解决办法
-
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
-
Android 开发手机(三星)拍照应用照片旋转问题解决办法
-
windows10不能获取有效IP的问题
-
会声会影注册表怎样清理 清理会声会影残留解决安装问题的方法
-
解决160wifi打开失败、无法共享以及手机无法上网的问题
-
ZCF提出解决零确认交易安全问题新方案