栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

从零开始学GeoServer源码八(内存溢出?Out of Memory Error ?)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从零开始学GeoServer源码八(内存溢出?Out of Memory Error ?)

目录
  • 1.前言
  • 2.有哪些现象?
    • 2.1 所有进程的内存加起来远远没有显示的那么高
    • 2.2 我们自己的服务都取消开机启动,重启服务器之后,这些服务未运行,但是服务器的内存还是在一直上涨。
  • 3.排查服务器问题
    • 3.1 安装杀毒软件
    • 3.2 对进程进行一一排查
  • 4.排查GeoServer问题
    • 4.1 安装jvisualvm的visualGC插件
    • 4.2 谁是凶手
      • 4.2.1 java.lang.ref.Finalizer
      • 4.2.2 com.sun.jna.Memory$LinkedReference
      • 4.2.3 com.sun.jna.Memory$SharedMemory
      • 4.2.4 com.sun.jna.Structure$AutoAllocated
    • 4.3 是谁调用了它们
  • 5.解决问题
  • 6.总结

1.前言

  本篇博文可以说是一次 GeoServer 线上内存溢出的解决过程,因为我们线上发布以后,发现 GeoServer 的内存一直在上涨,最终导致无内存可用,发生了内存溢出(Out of Memory Error),但是当我们排查了一遍问题以后发现,不仅仅是 GeoServer 的问题,还有很多问题,都导致了最终无内存可用,接下来详细说明。

2.有哪些现象?

  出现内存溢出以后,我们就开始排查问题,结果发现了这么几个现象。

2.1 所有进程的内存加起来远远没有显示的那么高

推测导致这个问题的原因可能是服务器上有病毒,被挖矿了

2.2 我们自己的服务都取消开机启动,重启服务器之后,这些服务未运行,但是服务器的内存还是在一直上涨。

推测可能是某个其他程序造成了内存泄露,而泄露的内存并没有显示在资源管理器里面,所以我们看不到。所以,不只是 GeoServer 有问题,服务器也有问题。

3.排查服务器问题 3.1 安装杀毒软件

  虽然我很不愿意在服务器上安装360,但是到了这一步,死马当做活马医吧,装上之后立刻进行木马扫描,还真的扫出来病毒!!!处理之后服务器重启,内存仍然在上涨,那就说明还有问题。

3.2 对进程进行一一排查

  具体就是,将某个进程(非系统进程)结束,看看内存是否还在上涨?这样一个个排查下来以后,还真的发现了一个进程,叫做 vendor license manager ,将其关闭之后,发现内存终于稳定了。

奇怪的是这个进程是自启动的,结束之后,过一会儿又会自动跑起来,占用的内存也不多,大概也就4-5M,所以一开始并没有出现在我们关注的视野里。最后,在任务管理器右键打开这个进程所在的位置,将其对应的exe文件重命名为了exe1,终止了其自启。这简直就是他喵的就是个病毒。

4.排查GeoServer问题 4.1 安装jvisualvm的visualGC插件

  对 GeoServer 的排查就要借助 jdk 自带的工具 jvisualvm 了,这个工具在 jdkbin 目录下,双击打开即可。为了能直观的看到它的内存回收过程,我们装上 visualGC 插件。

然后就是要看它的内存中到底哪个类的实例比较多了

抽样器的内存中显示的实时的动态过程,我们也可以点击右上角的 堆Dump 按钮,看到当前时刻的堆中实例的情况。

经过一段时间的对比发现,以上四个类的实例对象增长的速度贼快,于是我们打开 IDEA ,查看一下这几个类到底是何方神圣。

4.2 谁是凶手

IDEA 开始 debug ,在这几个类的构造函数里打上断点,看看到底干了什么?

4.2.1 java.lang.ref.Finalizer

4.2.2 com.sun.jna.Memory$LinkedReference

这是个静态内部类:

4.2.3 com.sun.jna.Memory$SharedMemory

这就是个普通的内部类:

4.2.4 com.sun.jna.Structure$AutoAllocated

这也是一个内部静态类:

4.3 是谁调用了它们

  直接看调用栈,原来是 org.geoserver.system.status.OSHISystemInfoCollector ,好家伙,终于找到元凶了,这个类是用来获取操作系统状态的,这里面写了一个死循环,只要程序还在运行,死循环里就一直在 new 那几个类。

5.解决问题

  知道了问题所在,就好解决了,通过 google 可知,这个类所属的包 com.github.oshi.oshi-core 的 5.5.1 版本是存在内存泄露问题的,很不幸,我们程序中引用的就是 5.5.1 ,改为 5.8.0 ,经过测试,程序终于正常了。

6.总结

  Java 内存泄露或者内存溢出问题解决起来还是挺费劲的,因为可能不仅仅是程序的问题,本文中的各种问题,前前后后经过了一周才得以彻底解决。不过对于 Java 程序员来说,没有经过 JVM 调优 和 内存溢出问题排查,是不完整的,这句话,只有多年代码经验的人才能深刻体会。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/831456.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号