在多个帖子中提到:不当使用ThreadLocal原因内存泄漏.我正在努力了解内存泄漏将如何发生ThreadLocal.
我发现它的唯一情况如下:
Web服务器维护一个线程池(例如,用于servlet).如果
ThreadLocal没有删除变量,那些线程可以创建内存泄漏,因为线程没有死亡.
这种情况没有提到"Perm Space"内存泄漏.这是内存泄漏的唯一(主要)用例吗?
我们正在创建多个子类加载器,以将多个子应用程序加载到Java应用程序"容器"中,进行热部署原型设计.当特定类加载器的类路径发生更改(即已添加,删除,更新了jar)时,旧的类加载器将被丢弃(未引用),并为新的jar类路径创建新的类加载器.
更新类路径,触发热部署后,我们进行了堆转储.堆转储(使用Memory Analyzer)表明旧的类加载器没有被垃圾回收.父类加载器中的某些类正在缓存旧的类加载器.调用以下内容来清除这些缓存:
java.lang.ResourceBundle.clearCache(classLoader);
org.apache.commons.logging.LogFactory.release(classLoader);
java.beans.Introspector.flushCaches();
Run Code Online (Sandbox Code Playgroud)
即使在清除了上述缓存之后,旧的类加载器仍然没有被垃圾收集.对类加载器的其余引用包括以下内容:
以上所有都是类加载器中的循环引用,它应该触发垃圾回收.我不确定为什么不是.有没有人知道为什么旧的类加载器仍然没有被垃圾收集,即使有循环引用?
我有一个在Tomcat 7上运行的Java Web应用程序似乎有内存泄漏.应用程序的平均内存使用量在负载下随着时间线性增加(使用JConsole确定).在内存使用率达到稳定水平后,性能会显着下降.响应时间从~100ms到[300ms,2500ms],所以这实际上是造成实际问题.
我的应用程序的JConsole内存配置文件:

使用VisualVM,我看到至少有一半的内存被字符数组(即char [])使用,并且字符串的大多数(大致相同数量的每个,300,000个实例)是以下之一:"分配失败" ,"复制","次要GC的结束",所有这些似乎都与垃圾收集通知有关.据我所知,应用程序根本不监视垃圾收集器.VisualVM找不到任何这些字符串的GC根,所以我很难跟踪它.
内存分析器堆转储:

我无法解释为什么内存使用量会如此高,但我有一个关于为什么性能一旦降低就会降低的理论.如果内存碎片化,应用程序可能需要很长时间才能分配连续的内存块来处理新请求.
将其与内置的Tomcat服务器状态应用程序进行比较,内存会增加并保持稳定,但不会像我的应用程序那样达到很高的"底限".它也没有大量无法访问的char [].
Tomcat服务器状态应用程序的JConsole内存配置文件:

Tomcat服务器状态applicationp的内存分析器堆转储:

这些字符串可以在哪里分配,为什么它们不被垃圾收集?是否存在可能影响此问题的Tomcat或Java设置?是否有特定的包可能会影响这个?
我正在使用 6.0.20 我在服务器上运行了许多 Web 应用程序,随着时间的推移,大约 3 天,服务器需要重新启动,否则服务器崩溃并变得无响应。
我有以下 JVM 设置:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=c:\tomcat\Websites\private\mydomain\apache-tomcat-6.0.20\logs
Run Code Online (Sandbox Code Playgroud)
这为我提供了一个 hprof 文件,我使用 Java VisualVM 加载了该文件,该文件标识了以下内容:
byte[] 37,206 Instances | Size 86,508,978
int[] 540,909 Instances | Size 55,130,332
char[] 357,847 Instances | Size 41,690,928
Run Code Online (Sandbox Code Playgroud)
列表还在继续,但我如何确定导致这些问题的原因?
我正在使用 New Relic 来监控 JVM,似乎只出现了一个错误,但它是一个重复出现的错误,org.apache.catalina.connector。客户端中止异常。是否有可能在用户会话中止时,创建的任何数据库连接或变量都没有关闭,从而成为孤立的?
有一个函数在每个 Web 应用程序中都被大量使用,不确定这是否与泄漏有关:
public static String replaceCharacters(String s)
{
s = s.replaceAll(" ", " ");
s = s.replaceAll(" ", "_");
s = s.replaceAll("\351", "e");
s = s.replaceAll("/", "");
s = s.replaceAll("--", "-");
s = s.replaceAll("&", "and");
s = …Run Code Online (Sandbox Code Playgroud)