Tomcat MemoryLeak 问题
来源:互联网 发布:美业邦软件的弊端 编辑:程序博客网 时间:2024/05/22 03:19
Tomcat reload memoryleak 错误描述
此现象发生在tomcat reload过程中多见。
我们的线上环境是使用jenkins远程部署,在部署重启中出现memory leak错误提示
环境:
tomcat7、jdk1.8
问题原因定位:
jvm默认定义了三种classloader,分别是bootstrap classloader、extension classloader、system classloader 。采用的是双亲委托机制进行加载。
tomcat7的加载模型如图
注意此处tomcat的类加载方式不完全遵循双亲委派模型,其中对于应用级别的加载各个web应用自己的类加载器(WebAppClassLoader)会优先加载,如果加载不到才走commonClassLoader走双亲方式。
当tomcat发生relaod的时候会执行org.apache.catalina.loader.WebappLoader下的backgroundProcess方法
public void backgroundProcess() { if (reloadable && modified()) { try { Thread.currentThread().setContextClassLoader (WebappLoader.class.getClassLoader()); if (container instanceof StandardContext) { ((StandardContext) container).reload(); } } finally { if (container.getLoader() != null) { Thread.currentThread().setContextClassLoader (container.getLoader().getClassLoader()); } } } else { closeJARs(false); } }
此处会判断reloadable 和modified(),即是否允许reload并且产生修改。再看下是如何reload的,此部分在org.apache.catalina.core.StandardContext下的reload方法
public synchronized void reload() { // Validate our current component state if (!getState().isAvailable()) throw new IllegalStateException (sm.getString("standardContext.notStarted", getName())); if(log.isInfoEnabled()) log.info(sm.getString("standardContext.reloadingStarted", getName())); // Stop accepting requests temporarily. setPaused(true); try { stop(); } catch (LifecycleException e) { log.error( sm.getString("standardContext.stoppingContext", getName()), e); } try { start(); } catch (LifecycleException e) { log.error( sm.getString("standardContext.startingContext", getName()), e); } setPaused(false); if(log.isInfoEnabled()) log.info(sm.getString("standardContext.reloadingCompleted", getName())); }
那么再回到问题quartz等线程没有被回收,重启前还有在其他地方引用的线程则gc无法回收。就会报上述错误。
解决方法:
1、应用使用的jesery,检测在servlet关闭的时候处理你要关闭的对象和线程
public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub System.out.println("reload Tomcat .... waiting >>>> manual close to prevent memory leak !!!!!! --- Today "); //sql this.shutDownSql(); //Jms this.shutDownJms(); //Quertz this.shutDownQuertz(); //Thread this.shutDownThread(); System.out.println("reload Tomcat .... over >>>> Its a happy day !!! --- Today"); }
2、Tomcat的实现是通过WeakHashMap来实现弱引用的,将WebappClassLoader对象放置到WeakHashMap中
private Map<ClassLoader, String> childClassLoaders = new WeakHashMap<ClassLoader, String>();public String[] findReloadedContextMemoryLeaks() { 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()]); }
- Tomcat MemoryLeak 问题
- 分析Java 死锁以及MemoryLeak问题
- 分析Java 死锁以及MemoryLeak问题
- 【tomcat】 tomcat 一些问题
- TOMCAT问题
- tomcat问题
- tomcat问题
- tomcat问题
- tomcat问题
- Tomcat问题
- Tomcat 问题
- Binder和BinderProxy实例会跨进程,检查MemoryLeak时得同时点GC
- 关于tomcat奇怪问题
- Tomcat使用中的问题
- tomcat中文问题
- Tomcat 5中文问题
- tomcat 三个问题
- Tomcat 中的JVM问题
- Redis 常见 的几种使用场景
- mysql之explain详解(分析索引的最佳使用)
- 解决Warning:com.alipay.sdk.sys.b: can't find referenced class com.ta.utdid2.devi
- Android相机实时自动对焦的完美实现
- 【jzoj5223】【GDOI2018模拟7.12】【B】【矩阵乘法】
- Tomcat MemoryLeak 问题
- 118. Pascal's Triangle
- Spring Boot 日志配置(超详细)
- Opencv 中cv开头的函数和没有cv的区别,例如cvWaitkey()和waitKey()的区别
- 自定义控件之自定义xmlns
- linux c++ 简易聊天室
- springmvc从数据库中读取数据并且显示成选择框
- Crontab 使用说明
- mysql5.7设置密码安全级别 ERROR 1819 (HY000): Your password does not satisfy the current policy requirements