Tomcat如何检测内存泄漏
一般情况下,如果我们重启web应用是通过重启tomcat的话,则不存在内存泄漏问题。但如果不重启tomcat而对web应用进行重加载则可能会导致内存泄漏,因为重加载后有可能会导致原来的某些内存无法让GC回收,例如web应用使用了JDBC,驱动会进行注册,当web应用停止时没有反注册就会导致内存泄漏。
看看是什么原因导致tomcat内存泄漏的。这个要从热部署开始说起,因为tomcat提供了不必重启容器而只需重启web应用以达到热部署的功能,其实现是通过定义一个WebappClassLoader类加载器,当热部署时就将原来的类加载器废弃并重新实例化一个WebappClassLoader类加载器。但这种方式可能存在内存泄漏问题,因为ClassLoader是一个结构复杂的对象,导致它不能被GC回收的可能性比较多,除了对ClassLoader对象有引用可能导致其无法回收,还可能对其加载的元数据(方法、类、字段等)有引用都会导致无法被GC回收。
如上图,tomcat的资源由不同类加载器加载,这里只看BootstrapClassLoader和WebappClassLoader两个类加载器,BootstrapClassLoader负责加载rt.jar包的java.sql.DriverManager,WebappClassLoader负责加载web应用中的mysql驱动包,其中有一个很重要的步骤是mysql的驱动类需要注册到DriverManager中,即DriverManager.registerDriver(new Driver()),它由mysql驱动包自动完成。这样一来当web应用进行热部署操作时,没有将mysql的Driver从DriverManager中反注册掉的话,则会导致整个WebappClassLoader回收不了,造成内存泄漏。
接着看tomcat如何对此内存泄漏进行监控的,要判断WebappClassLoader会不会导致内存泄漏只需判断WebappClassLoader有没有被GC回收即可。在Java中有一种引用叫弱引用,它能很好判断WebappClassLoader有没有被GC回收,被弱引用关联的对象只能生存到下一次垃圾回收发生之前,即如果某WebappClassLoader对象只被某弱引用关联,则它会在下次垃圾回收时被回收,但如果WebappClassLoader对象除了被弱引用关联外还被其他对象强引用,那么WebappClassLoader对象是不会被回收的,根据这些条件就可以判断是否有WebappClassLoader内存泄漏了。
Tomcat的实现是通过WeakHashMap来实现弱引用的,只需将WebappClassLoader对象put到WeakHashMap中,例如weakMap.put(“a”,webappClassLoader),当webappClassLoader及其包含的元素没有被其它任何类加载器中的元素引用到时,JVM发生垃圾回收时则会把webappClassLoader对象回收。
简单的实现代码大致如下:
public class MemoryLeakTest{
private Map<ClassLoader, String> childClassLoaders = new WeakHashMap<ClassLoader, String>();
public String[] findReloadedContextMemoryLeaks() {
System.gc();
List<String> result = new ArrayList<String>();
for (Map.Entry<ClassLoader, String> entry : childClassLoaders.entrySet()) {
ClassLoader cl = entry.getKey();
if (!((WebappClassLoader) cl).isStarted()) {
result.add(entry.getValue());
}
}
return result.toArray(new String[result.size()]);
}
}
使用一个WeakHashMap用于跟踪WebappClassLoader,在查找内存泄漏之前会先强制调用System.gc();进行一次垃圾回收,保证没问题的WebappClassLoader都被回收掉,这时如果还有WebappClassLoader的状态是非started(正常启动的都为started,关闭了的则为非started)的,则是未被垃圾回收的WebappClassLoader,属于内存泄漏的。
喜欢java的朋友可以加个好友:
Tomcat如何检测内存泄漏的更多相关文章
- Android性能优化之利用LeakCanary检测内存泄漏及解决办法
前言: 最近公司C轮融资成功了,移动团队准备扩大一下,需要招聘Android开发工程师,陆陆续续面试了几位Android应聘者,面试过程中聊到性能优化中如何避免内存泄漏问题时,很少有人全面的回答上来. ...
- 使用Visual Leak Detector检测内存泄漏[转]
1.初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题 ...
- monkey检测内存泄漏
monkey中检查内存泄漏,实际上是对一个操作多次操作后看内存情况,内存泄漏具体的原理可百度,现在我们梳理检测内存泄漏的方法: 测试前你需要安装: 1.MAT分析工具 2.使用工具事实监控内存指标,现 ...
- Qt creator 搭配 valgrind 检测内存泄漏
继上次重载operator new检测内存泄漏失败之后,妥协了.决定不管是否是准确指明哪一行代码出现内存泄漏,只要告诉我是否有泄漏就行了,这样就没有new替换的问题.在开发中,总是一个个小功能的开发. ...
- VC使用CRT调试功能来检测内存泄漏
信息来源:csdn C/C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:“最大的长处也可能成为最大的弱点”,那么 C/C++ 应用程序正好印证了这句话.在 C/C+ ...
- 如何在linux下检测内存泄漏
之前的文章应用 Valgrind 发现 Linux 程序的内存问题中介绍了利用Linux系统工具valgrind检测内存泄露的简单用法,本文实现了一个检测内存泄露的工具,包括了原理说明以及实现细节. ...
- 重载new和delete来检测内存泄漏
重载new和delete来检测内存泄漏 1. 简述 内存泄漏属于资源泄漏的一种,百度百科将内存泄漏分为四种:常发性内存泄漏.偶发性内存泄漏.一次性内存泄漏和隐式内存泄漏. 常发性指:内存泄漏的代 ...
- Vc 检测内存泄漏
启用内存泄漏检测 检测内存泄漏是 C/c + + 调试器和 C 运行时库 (CRT) 的主要工具调试堆函数. 若要启用调试堆的所有函数,在 c + + 程序中,按以下顺序包含以下语句: C++复制 # ...
- 如何在linux下检测内存泄漏(转)
本文转自:http://www.ibm.com/developerworks/cn/linux/l-mleak/ 本文针对 linux 下的 C++ 程序的内存泄漏的检测方法及其实现进行探讨.其中包括 ...
随机推荐
- jvm(二):内存管理
jvm内存区域总体分为5大块:方法区,java堆,虚拟机栈,本地方法栈,程序计数器,按照线程来分的话又分为线程共享区和线程独占区 程序计数器: a.程序计数器是一块较小的内存空间,可以看做是当前线程所 ...
- openwrt 下添加sim760ce usb驱动
SIM7500_SIM7600 系列模块的 USB VID 是 0x1E0E PID 是 0x9001. 作为 Slave USB 设备,配置如下表 USB 接口波特率自适应 9600.115200 ...
- Linux学习之CentOS(十六)-----内存置换空间(swap)之建置(转)
内存置换空间(swap)之建置 安装时一定需要的两个 partition 啰! 一个是根目录,另外一个就是 swap(内存置换空间), swap 的功能就是在应付物理内存不足的情况下所造成的内存延伸记 ...
- swift 初始化
知识点总结: 1.结构体 1.1.默认初始化方法:1.空初始化方法:2.成员初始化方法 struct Person{ var name = "tom" var age = } le ...
- redis锁处理并发问题
redis锁处理并发问题 redis锁处理高并发问题十分常见,使用的时候常见有几种错误,和对应的解决办法. set方式 setnx方式 setnx+getset方式 set方式 加锁:redis中se ...
- CI数据库操作_查询构造器类
=================数据库操作======================1.数据库配置: config/database.php 用户名 密码 数据库 2 加载数据库类:$this-& ...
- echarts——各个配置项详细说明总结
前 言 最近做了个关于各种图表的项目,用到了echarts , 关于各个配置项刚开始用好多都不懂,有些地方需要改不知道改哪个参数,就在网上查了各种,总结规整了一下,跟大家分享学习一下.(e ...
- Laravel-admin 七牛云上传文件到七牛云出现卡顿失败情况
由于所做项目需要管理后台众多,所以选择了Laravel-admin后台框架进行开发.节省了权限控制以及页面处理等问题的时间 Laravel-admin文档地址 http://laravel-admin ...
- python环境搭建(python2和python3共存)
安装两个版本的意义 验证自己代码对版本的兼容性 网上下载的某些源码只能在python2或者python3中运行 安装过程记录 1.去python官网下载python的安装包, 下载完成后如下图所示 2 ...
- Stall Reservations
Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked ...