草庐IT

java - 即使没有 gc 根,WebappClassLoader 内存泄漏

coder 2024-04-02 原文

HERE IS THE HEAD DUMP (UPDATED ON 10/29/2013)

我在一个网络应用中工作:

  • Tomcat 7.0.24
  • Java 6
  • Spring 3(使用 aop - cglib)
  • 基于 Log4j 的 SLF4J
  • Oracle 一致性

经过大量工作,我设法删除了所有对类加载器的强引用,现在它是垃圾收集器的候选者。那么,内存泄漏解决了吗?当然不是!因为在几次热部署之后,由于 PermGen 空间出现了 OOME。

感谢 Yourkit,我能够检查 WebappClassLoaderPending Finalization 这意味着它正在终结队列中等待(实际上,不是 WebappClassLoader 本身就是他的一个referents)。检查内存快照时,我发现了几个对 Oracle Coherence 类的 Finalizer 引用...

这看起来很“好”:Coherence 对象正在等待垃圾回收,这要归功于移除所有强引用所做的所有艰苦工作(杀死所有 coherence 线程,移除 java 安全提供程序等)。我认为这里没有什么可做的。

所以,我在考虑一些 finalize 执行会破坏某些东西,然后不允许清空终结器队列。但奇怪的是,使用 JMX 或 jmap -finalizerinfo 终结器队列似乎是空的!这一切都非常令人困惑,所以我一直在其他地方搜索......

你认为这是这里要做的事吗? 我读过一些关于 CGLIB enhancing the finalize method 的东西.如果我有权访问 Enhancer,我可以按照说明创建一个回调过滤器 here但我不知道如何使用 Spring AOP 来管理它。

好吧,在其他地方搜索,我发现了几个来自 java.lang.reflect.Proxy 的弱引用。这些是 jdk 动态代理吧?或者它们与内省(introspection)内存泄漏有关?弱引用?

信息:我正在使用 Spring 的上下文监听器来刷新 Instrospector 的缓存 (java.beans.Introspector.flushCaches())。 我还能用它做什么?

让我们继续。

然后,我们还有来自 java.io.ObjectStreamClass$Caches 的其他几个弱引用。我的很多业务对象都有这种弱引用。

也许我需要刷新这些缓存。 但是如何呢??

然后我们有这些与 com.sun.internal.ResourceManagerjava.util.logging.Loggingjava.lang.reflect 相关的弱引用。代理

我能用这个弱引用做什么?我需要担心这个还是问题出在终结器队列上?任何线索都会有帮助......真的:-D

啊,还有一件事,我从 tomcat 的“主”线程中发现了一个弱引用,它永远不会被 tomcat 更新。我知道我的应用程序可以在某些 tomcat 线程中保留一些线程局部变量,但是 tomcat 7 renew these threads to avoid class loader memory leaks .

我认为这是我的内存快照中最奇怪的东西,但这是弱引用吗?我可以用它做什么?

编辑:阅读java.lang.ref javadoc我发现了这个:

An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing a weak reference. When the weak references to a weakly-reachable object are cleared, the object becomes eligible for finalization.

那么,弱引用在实现finalize方法时是否可以保留堆中的对象?

与此同时,我找到了这个问题的答案,我设法删除了所有对我的类加载器的弱引用,除了两个:ClassLoaderLogManager.classLoaderLoggers 和与 tomcat 线程相关的那个。

注意:实际上,我设法删除了第一个,但此引用在取消部署之后/期间由 tomcat 再次设置。

编辑:PLUMBR 结果

我已经尝试过 plumbr,但在 Web 控制台上没有任何报告。标准输出上只有这条消息

Dumping heap to /opt/tomcat7/headdumps/java_pid9478.hprof ...
Heap dump file created [348373628 bytes in 3.984 secs]
#
# An unexpected error has been detected by Java Runtime Environment:
#
#  Internal Error (javaCalls.cpp:40), pid=9478, tid=1117813056
#  Error: guarantee(!thread->is_Compiler_thread(),"cannot make java calls from the compiler")
#
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.2-b01 mixed mode linux-amd64) [thread 1110444352 also had an error]
# An error report file with more information is saved as:
# [thread 1110444352 also had an error]
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#
******************************************************************************
*                                                                            *
* Plumbr has noticed that JVM has thrown an OutOfMemoryError: PermGen space. *
*                                                                            *
* You can increase PermGen size with -XX:MaxPermSize parameter.              *
* If you encountered this error after a redeploy, please read next article:  *
* http://plumbr.eu/blog/what-is-a-permgen-leak                               *
*                                                                            *
******************************************************************************

最佳答案

我认为 Yourkit 将您引向了错误的道路。

我已经使用 Eclipse 内存分析器查看了您的堆转储。它表明,WebappClassLoader 被类 com.inovasoftware.iap.data.access.platform.datarepository.CoherenceDataRepository$$EnhancerByCGLIB$$180c0a4e 引用,该实例在某个线程局部变量中处于 Activity 状态。一些谷歌搜索显示: https://hibernate.atlassian.net/browse/HHH-2481

因此升级 Hibernate 版本可能会有帮助。

关于java - 即使没有 gc 根,WebappClassLoader 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19470328/

有关java - 即使没有 gc 根,WebappClassLoader 内存泄漏的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  3. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  4. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  5. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  6. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  7. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  8. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  9. 没有类的 Ruby 方法? - 2

    大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow

  10. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

随机推荐