Author:
From:
http://java.dzone.com/articles/memory-leak-protection-tomcat?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+zones%2Fcss+%28CSS+Zone%29
The last time DZone spoke with Mark Thomas, a Senior Software Engineer with SpringSource and committer for Apache Tomcat, he said that Tomcat has had a long history of memory leaks when reloading web applications. This topic could easily fill its own article, he said. In his overview of the features coming in Tomcat 7, Thomas said that the new version, which is expected to have an alpha release next month, will address many of the memory leaks caused by web applications, their libraries, and even the JVM. He said that a small percentage of the leaks were caused by Tomcat, but those bugs were fixed several years ago. Now the challenge has been to come up with workarounds for the vast array of memory leak sources. In this exclusive interview with DZone, Thomas elaborates on these fixes coming in the next version of Apache Tomcat.
DZone: What typically causes a memory leak on web application reload and what symptoms might a developer see?
Mark Thomas: The usual symptom observed is an OutOfMemoryError (OOME) indicating that the Permanent Generation (PermGen) is exhausted when reloading a web application.
PermGen is where the JVM stores classes. Classes are stored in PermGen using class name and class loader as the unique identifier. Each web application has its own class loader; this allows different versions of the same class (with the same name) to be used in different web applications without conflict. A web application also gets a new class loader when it is reloaded. Classes are removed from PermGen when the class loader is collected by the garbage collector. This normally happens after a web application stops. However, if something retains a reference to the web application class loader, it won't be garbage collected and the classes it loaded will remain in PermGen. Since PermGen is limited in size, this usually only has to happen a few times before all the PermGen is used. That is when the OOME occurs.
To prevent the OOME, it is necessary to ensure that nothing retains a reference to the web application class loader.
DZone: Tell me about the Tomcat's history with memory leaks on web application reload.
Mark: Memory leaks on web application reload have been a problem for as long as I have been involved in the Tomcat project. Where the problem has been traced to a bug in the Tomcat code base, it has been fixed. There were a handful of such bugs fixed around the time of Tomcat 4.1.x / Tomcat 5.5.x that regularly caused problems. Since then there have been a few edge case bugs that occasionally caused problems and, again, these were fixed as they were found.
Historically, Tomcat has been blamed for causing these memory leaks but when investigated by the Tomcat developers, it usually emerged that the root cause was a bug in the web application or the library rather than Tomcat.
Around twelve months ago I was giving a presentation on Tomcat tuning and made an off-hand comment that the root cause of memory leaks on web application reload was application and/or library bugs rather than a Tomcat bug. This comment generated rather more feedback than I was expecting and I was soon working with a number of the attendees debugging their memory leaks.
The leaks that were traced to application or library bugs weren't unexpected. However, we also traced some leaks to usage of particular standard Java APIs and this was a surprise. As we worked to develop fixes for these, I realised that these fixes would be best placed as part of the standard Tomcat codebase. That became the starting point for the new memory leak protection.
The memory leak protection was enhanced by taking a number of web applications known to have memory leaks on reload and developing fixes and workarounds for each of the memory leaks found until the applications could be reloaded without triggering a memory leak. The combination of these fixes and workarounds became the new memory leak protection features that will be included in Tomcat 7 and has recently been back-ported to Tomcat 6.0.x (6.0.24 onwards).
DZone: So have all of the bugs causing memory leaks on Tomcat's end been fixed?
Mark: All the ones we know about! There are probably a few rarely encountered bugs remaining. These too, will get fixed as they are reported.
Tomcat's JVM Memory Profile
DZone: What are some of the bugs in web applications, their libraries, and the JVM that have caused memory leaks?
Mark: The memory leaks all fit a common pattern. The web application creates an object of a class loaded by the web application class loader and then places this object in a registry that has been loaded by a different
class loader. This is fine, as long as the object is removed from the registry when the web application stops. If the object is not removed, the registry retains a reference to the object, the object retains a reference to the class and the class retains a reference to the class loader. This pins the class loader in memory. This chain of
references prevents the class loader from being garbage collected which in turn means that the PermGen used to store classes loaded by this class loader cannot be freed.
Application or library code that can trigger this situation include:
- JDBC driver registration
- Some logging frameworks
- Storing objects in ThreadLocals and not removing them
- Starting threads and not stopping them
There are also a number of places that using the standard Java API can trigger a similar issue. These include:
- Using the javax.imageio API (the Google Web Toolkit can trigger this)
- Using java.beans.Introspector.flushCaches() (Tomcat does this to prevent memory leaks caused by this caching)
- Using XML parsing (the root cause is unknown due to a bug in the JRE)
- Using RMI (somewhat ironically, causes a leak related to the garbage collector)
- Reading resources from JAR files
DZone: Tell me about the work-arounds that Tomcat 7 will have for these bugs.
Mark: For the application or library code problems, Tomcat fixes problems where it can by de-registrating the object(s) that were registered by the application or library. Tomcat will also log any action taken so the web application developer can fix the root cause of the problem, rather than relying on Tomcat to fix the leak. This is especially important for threads that are not stopped since Tomcat can not do this safely.
The details of how Tomcat fixes these problems may be found in the clearReferences() method of the WebappClassLoader class.
For the Java API usages that can trigger a memory leak, these are all triggered if the first call to that API is made by a web application. Tomcat, therefore, prevents these leaks by ensuring that the core Tomcat code is the first to call these APIs, thereby making them safe for web applications to call.
The details of this protection can be in the JreLeakPreventionListener class.
The one exception to this is the java.util.logging Implementation (JULI). The logging framework provided by the JRE is not class loader aware and can quickly lead to memory leaks in a Servlet container environment. To address this, JULI replaces the standard LogManager with one that is class loader aware. This allows java.util.logging to be used without triggering a memory leak.
DZone: How much memory leak improvement do you think Tomcat 7 will have overthe current version?
Mark: The new features in Tomcat 7 and 6.0.24 onwards should offer significant improvements. However, it is likely that there are other causes of memory leaks since the investigations so far have only used a small number of web applications for testing. The new features in Tomcat should make it easier to track own these additional sources of memory leaks and, as they are identified, protection against them can be added to Tomcat.
DZone: How are things progressing on Tomcat 7 development and where is the community at right now as far as the roadmap is concerned? Is there a ballpark for it's release date?
Mark: Things are progressing well. The JSP & EL 2.2 implementation is complete and the Servlet 3.0 implementation is close to completion. I had hoped that Tomcat 7 would be ready for a first release by the end of January but it now looks as if it will happen in February.
DZone: Is there anything else you'd like to mention about Tomcat 7?
Mark: There has been lots of clean-up and other tweaks in Tomcat 7 but the one thing that I think is worth mentioning is improved support for embedding Tomcat. Whilst Tomcat has always been embeddable, it has been rather more complex than it needs to be. With Tomcat 7 we will be providing a simple API and a download option that provides all the Tomcat features but with a fewer number of JARs. Together, these changes will make it much easier to embed Tomcat in other applications.
Finally, the Tomcat community is always looking for new contributors. Whether it is answering questions on the users list, providing translations, fixing bugs, developing new features, improving the web site or something else, contributions are always welcome. The first step for people interested in contributing is to join the user and/or dev mailing list and let the Tomcat community know how they can help.
another useful wiki:
http://wiki.apache.org/tomcat/MemoryLeakProtection
相关推荐
This program is a tool that help you positioning memory leak locations of an QUALCOMM BREW application on simulator. It can give the call stack of memory leaks (including the locations that MALLOC/...
内存泄漏是程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄漏可能看似无足轻重,但随着时间推移,大量的内存泄漏会消耗掉系统可用内存,导致性能下降甚至系统崩溃。在C++编程中,由于手动管理内存的...
**BREW Memory Leak Checker** 是一个专为BREW(Binary Runtime Environment for Wireless)平台设计的工具,用于检测和定位BREW应用程序中的内存泄漏问题。在移动设备开发中,内存管理是至关重要的,因为有限的资源...
本文将深入探讨C++中的内存泄漏问题及其解决策略,并介绍两种常用的内存泄漏检测工具——Visual Leak Detector (VLD) 和 CodeSnitch。 内存泄漏的发生通常是由于以下原因: 1. 动态分配的内存未被释放:当使用`new`...
BREW Memory Leak Checker是一款专为BREW(Binary Runtime Environment for Wireless)平台设计的内存泄漏检测工具,版本号为20111030。该工具的主要功能是在BREW模拟器上帮助开发者定位并解决应用程序中的内存泄漏...
BREW Memory Leak Checker是一款专为BREW(Binary Runtime Environment for Wireless)平台设计的内存泄漏检测工具,版本号为20111109。该工具的主要功能是在BREW模拟器上帮助开发者定位并解决应用程序中的内存泄漏...
在C++编程中,内存泄漏是一个常见的问题,它发生在程序员分配了内存但未能正确地释放。这可能导致程序占用越来越多的内存,最终导致性能下降甚至崩溃。为了帮助开发者检测和修复内存泄漏,本压缩包提供了一个内存...
Glassfish 3.1.2.2 Web Service Memory Leak Workaround Glassfish 3.1.2.2 中的 Memory Leak 问题可能会导致服务器变慢或无响应。这种问题可能是由于 Web Service 的 Memory Leak 导致的。在此文中,我们将讨论...
JavaScript是一种广泛应用于Web开发的脚本语言,它在执行时占据内存资源,如果代码编写不当,可能会出现“内存泄漏”(Memory Leak)的问题。内存泄漏是程序运行时未释放不再使用的内存,导致系统资源浪费,严重时...
This program is a tool that help you positioning memory leak locations of an QUALCOMM BREW application on simulator. It can give the call stack of memory leaks (including the locations that MALLOC/...
Memory Leak(解决方案).md
"Android中Memory Leak原因分析及解决办法" Android中Memory Leak原因分析及解决办法是Android开发过程中的重要问题之一。Memory Leak是指在Android应用程序中,一些对象不能被正确释放,导致这些对象继续占用内存...
Memory Leak Detected(亲测可用).md
**7. 源码分析** 深入理解AngularJS源码有助于找出可能引发内存泄漏的特定代码片段。通过调试和分析,可以找到哪些部分需要优化或修复。 **8. 工具辅助** 使用内存分析工具,如Chrome DevTools或Firefox的Memory ...
编译器设计之代码分析工具:Memory Leak Detectors
1. `_CrtSetDbgFlag`: 这个函数允许我们设置调试标志,其中`_CRTDBG_LEAK_CHECK_DF`是用于开启内存泄漏检查的标志。通过在程序启动时调用`_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF)`,我们可以让程序在退出时报告内存...
内存泄漏检测器 MemoryLeakDetector是由Xigua视频android团队开发的本地内存泄漏监视工具。 它具有访问简单,监视范围广,性能...leak-detector:0.0.7 '} 步骤3:添加代码以方便使用(使用广播控件不需要此步骤) //
java