Tomcat与内存泄露处理的示例分析-成都创新互联网站建设

关于创新互联

多方位宣传企业产品与服务 突出企业形象

公司简介 公司的服务 荣誉资质 新闻动态 联系我们

Tomcat与内存泄露处理的示例分析

本篇文章给大家分享的是有关Tomcat与内存泄露处理的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

在墨脱等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都做网站、成都网站建设、成都外贸网站建设 网站设计制作按需制作,公司网站建设,企业网站建设,品牌网站建设,网络营销推广,外贸网站制作,墨脱网站建设费用合理。

但是随着开发经历的增长,已经开发过应用的增多,应用内需要加载的 class 增多,经常就会遇到内存溢出(OOM)。或者更确切的说,因为加载 class 的增多导致的内存溢出是java.lang.OutOfMemoryError: PermGen space

此时,解决OOM的方式一般是

  1. 分析应用的代码写的是否有问题,可以通过一些工具观察应用内占用内存较多的 class 类型 (比如通过 JVisualVM 来分析Java七武器系列多情环 --多功能Profiling工具 JVisual VM,或者通过MAT来分析)

  2. 修改 JVM启动参数,增大关于 Perm Gen 的配置。

在 Tomcat 这一类的 应用服务器中,由于其做为应用的容器运行,可能自身的Perm Gen 占用并不多,但需要考虑部署到容器中的应用占用。有些应用依赖了大量的第三方类库,也有一些应用会在运行时动态生成大量的 class,这些内容的加载,都容易导致 Perm Gen 的 OOM。

对于 OOM 的处理,内部会在启动时占用一小块内存,在 OOM 产生的时候释放掉来临时缓解一下,这种称为oomParachute。前面写过一篇介绍的文章(预防OOM,Tomcat是这样做的)。

除此之外,Tomcat 在 manager 应用中还提供了发现内存泄漏的功能。

Tomcat与内存泄露处理的示例分析

图上说明写的明白,该功能主要用于分析在应用停止、重部署、解除部署时是否造成了内存泄漏。 

在请求后,manager的上方信息显示区域会提示当前是否有应用造成的内存泄漏。

Tomcat与内存泄露处理的示例分析

但需要注意的是此功能会触发一次 Full GC 的执行,代码中使用的是 System.gc(),在生产环境中如果使用需要谨慎。

那么,在什么情况下会导致所谓的应用内存泄漏呢?

我们都知道, 为了实现应用间的 class 隔离, Tomcat 对于每个应用,都会单独使用一个 WebappClassLoader,这样,多个应用间即使都使用到一个 类库的不同版本,也不会相互影响造成冲突。 (参考前面的文章:Tomcat类加载器以及应用间class隔离与共享, 类加载器与类冲突)

但是,在这种情况下,当一个应用已经执行了停止操作,或者执行了重部署操作,此时是会生成一个新的 classLoader 来加载新部署的应用类信息。

我们知道,在 Java 中,类与类之间是存在引用关系的,类似于强引用,弱引用,幻影引用,用来在GC时将一些不需要的 class 回收掉,腾出空间。按理说之前的 classLoader 本应该被垃圾回收,但在某些时候,由于一些类之前的引用关系导致该 classLoader,以及其加载的一系列 class 文件, 都不能被标识为垃圾,此时这些 class 依然驻留在 Perm Gen,随着应用多次启停,多次重部署之后,出现了 Perm Gen 的 OOM。

一般以下类库的使用容易导致 class loader 逃过垃圾回收,产生内存泄漏:

  • JDBC driver 注册

  • 一些 logging 框架

  • 没有移除的 ThreadLocal的使用

  • 未停止的 Thread

此外,一些 Java API 的使用也容易导致此问题,例如

  • javax.imageio API

  • XML 解析 

  • RMI 使用

由于这些容易占用 classLoader,导致其不能被回收,如果这些 class 交给各个应用的类加载器进行加载,就会使得 Perm  Gen 中这些类越来越多,从而产生泄漏。

为此,在 Tomcat 中引入了 JreMemoryLeakPreventionListener这个组件。实现思路是在 Tomcat 启动时,通过 System class Loader 来加载这些类。 由于类加载器的加载原理(默认父优先,而且这些系统的类,都会委托给系统类加载器进行加载),这些类不会再被 WebclassLoader 重新加载,从而减小内存泄漏的产生。

默认在 Tomcat 的配置 server.xml 中已经开启了该组件,所以这些功能你已经不知不觉中在使用。

以上就是Tomcat与内存泄露处理的示例分析,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。


标题名称:Tomcat与内存泄露处理的示例分析
文章路径:http://kswsj.cn/article/pjpieh.html

其他资讯