Tomcat 检测内存泄漏实例详解
发布时间 - 2026-01-10 22:14:16 点击率:次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,属于内存泄漏的。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# Tomcat如何检测内存泄漏
# Tomcat检测内存泄漏详解
# 详解如何通过tomcat的ManagerServlet远程部署项目
# servlet和tomcat_动力节点Java学院整理
# tomcat中Servlet对象池介绍及如何使用
# tomcat中Servlet的工作机制详细介绍
# Tomcat报错:HTTP Status 500 (Wrapper cannot find serv
# tomcat报错:Wrapper cannot find servlet class ...问题解决
# Spring关闭Tomcat Servlet容器时内存泄漏问题解决方案
# 加载
# 重启
# 只需
# 是一个
# 就会
# 很好
# 则是
# 中有
# 会不会
# 对其
# 希望能
# 不存在
# 很重要
# 时就
# 会把
# 谢谢大家
# 只看
# 则可
# 它能
# 而对
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
详解CentOS6.5 安装 MySQL5.1.71的方法
Laravel怎么自定义错误页面_Laravel修改404和500页面模板
如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框
如何用PHP快速搭建高效网站?分步指南
Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优
使用C语言编写圣诞表白程序
Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
bootstrap日历插件datetimepicker使用方法
如何用免费手机建站系统零基础打造专业网站?
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】
清除minerd进程的简单方法
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】
Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤
,南京靠谱的征婚网站?
网站制作软件有哪些,制图软件有哪些?
晋江文学城电脑版官网 晋江文学城网页版直接进入
如何用PHP快速搭建CMS系统?
MySQL查询结果复制到新表的方法(更新、插入)
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
如何快速搭建二级域名独立网站?
微信小程序 input输入框控件详解及实例(多种示例)
Laravel如何配置任务调度?(Cron Job示例)
Laravel如何与Pusher实现实时通信?(WebSocket示例)
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程
手机网站制作与建设方案,手机网站如何建设?
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
Laravel如何实现多对多模型关联?(Eloquent教程)
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤
JavaScript实现Fly Bird小游戏
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
JavaScript常见的五种数组去重的方式
高性价比服务器租赁——企业级配置与24小时运维服务
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
Laravel如何生成API文档?(Swagger/OpenAPI教程)
如何用VPS主机快速搭建个人网站?
个人网站制作流程图片大全,个人网站如何注销?
Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】
laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法
如何快速打造个性化非模板自助建站?
如何在云主机上快速搭建多站点网站?
高端建站三要素:定制模板、企业官网与响应式设计优化

