手机有办法扩大内存吗,手机有办法去除马赛克吗

  

  大家好,我是大斌~   

  

  今天,我想和大家分享一下最近的OOM问题。   

  

  上周五早上,测试学生报告测试环境的子系统服务超时,请求没有响应。   

  

  收到这个问题后,我有点疑惑。最近这个系统没有改变代码逻辑,怎么会突然报错服务超时?为了避免影响测试进度,我赶紧登录堡垒机器查看日志,看看到底是怎么回事。   

  

  首先查看系统负载,并使用top命令进行检查。发现一个Java进程的cpu一直停留在100%到200%之间。因为这个系统不涉及大量运算的逻辑,所以可以猜测要么是无限循环的问题,要么是频繁的满gc的问题。   

  

     

  

  查看系统日志,发现出现java.lang.out内存错误:元空间。显然,元空间内存溢出。   

  

  然后检查系统gc,并使用以下命令进行检查。Pid是对应的Java进程id,由top命令获得。参数1000表示每1000毫秒打印一次记录。   

  

  jstat -gc pid 1000一看执行结果,果然,从应用启动到采样,全gc已经触发了上百次!这也是cpu一直是100%的原因。   

  

     

  

  还有一个参数MC(元空间分配的内存大小),接近设置的最大元空间大小(配置- XX:MaxMetaspaceSize=128m)。   

  

  这里也简单介绍下元空间。   

  

  元数据是jdk8特有的数据结构,称为永久生成。到了jdk8的永久代,就会被抛弃,被元空间取代。元空间分配在本地内存中(而不是堆上),默认情况下内存使用不受限制。您可以使用MaxMetaspaceSize指定最大值。   

  

  元空间由两部分组成。   

  

  Klass元空间用于存储klass,klass是jvm中类文件的运行时数据结构。   

  

  NoKlass元空间,专用于存储与Klass相关的其他内容,如方法、常量池等。这个记忆是由多个记忆片段组成的。   

  

  是由mcklass元空间和NoKlass元空间分配的总内存大小,以KB为单位。上图中MC接近元空间设置上限,即此时元空间内存不够,导致一直触发满gc。   

  

  然后对转储内存进行分析,看看是什么导致了元空间内存溢出。使用命令。/jmap-dump3360Live,format=b,file=/xxx将内存堆导出到xxx位置(hprof格式),然后使用mat工具进行分析。   

  

  将hprof文件导入MAT工具,打开内存泄漏分析(涉及公司内部源代码,所以是马赛克):   

  

     

  

  看到这里,我大概就知道问题出在哪里了。最近公司在推广一个漏洞监控工具,需要在服务器上部署代理程序。该工具可以收集和监控应用程序运行时的功能执行和数据传输,并可以识别常见的安全缺陷和漏洞。编码部分是这个漏洞监控工具的应用包名称,很可能是这个工具的引入导致的问题!   

  

  进一步确认问题。打开直方图:   

  

     

  

  Loweheap表示对象结构自身,占用的内存大小,不包括其属性引用对象占用的内存。   

  

  Retained Heap是对象被GC回收后可以释放的内存大小,它等于释放对象的保留堆中所有对象的shallowheaps的总和。   

  

  在直方图视图中,选择其中一个类,然后单击鼠标右键弹出一个菜单。选择“合并到GC根的最短路径”来查看当前对象到GC根的路径,并且可以过滤某些类型的引用。   

  

     

  

  结果如下:   

  

     

  

  占用内存空间最大的类是漏洞监控工具,基本可以确定问题。   

  

  在删除并重新部署最后一个漏洞监控工具后,将不会出现服务超时问题。   

  

  以上是本期OOM问题分析的全过程~   

  

  码字不容易,如果觉得有帮助,可以在点个赞!鼓励一下   

  

  我是程序员大斌,重点分享Java后端的硬核知识。欢迎关注~   

相关文章