内存是否泄漏?为什么java.lang.ref.Finalizer会占用这么多内存

内存是否泄漏?为什么java.lang.ref.Finalizer会占用这么多内存,java,memory,finalizer,proxool,Java,Memory,Finalizer,Proxool,我在我的程序上运行了一个堆转储。当我在内存分析器工具中打开它时,我发现org.logicalcbwebs.proxool.ProxyStatement的java.lang.ref.Finalizer占用了大量内存。为什么会这样 有些类实现了对象.finalize()方法。重写此方法的对象需要由后台线程调用终结器调用,并且在发生这种情况之前无法清理它们。如果这些任务很短,并且你没有放弃其中的许多任务,那么一切都会很好。但是,如果要创建大量这些对象和/或它们的终结器需要很长时间,那么要终结的对象队列

我在我的程序上运行了一个堆转储。当我在内存分析器工具中打开它时,我发现
org.logicalcbwebs.proxool.ProxyStatement
java.lang.ref.Finalizer
占用了大量内存。为什么会这样


有些类实现了
对象.finalize()
方法。重写此方法的对象需要由后台线程调用终结器调用,并且在发生这种情况之前无法清理它们。如果这些任务很短,并且你没有放弃其中的许多任务,那么一切都会很好。但是,如果要创建大量这些对象和/或它们的终结器需要很长时间,那么要终结的对象队列就会建立起来。此队列可能会耗尽所有内存

解决办法是

  • 如果可以,不要使用finalize()d对象(如果您正在为对象编写类)
  • 使finalize非常简短(如果必须使用它)
  • 不要每次都丢弃此类对象(尝试重新使用)

最后一个选项可能最适合您,因为您正在使用现有的库。

据我所知,Proxool是用于JDBC连接的连接池。这向我表明,问题在于您的应用程序误用了连接池。您的代码可能正在删除语句对象和/或它们的父连接,而不是对语句对象调用
close
。Proxool依赖终结器关闭底层驱动程序实现的对象。。。但这需要那些终结器实例。这也可能意味着您导致连接打开/关闭(真实)数据库连接的频率超过了必要的频率,这将对性能造成不利影响

因此,我建议您检查代码中泄漏的结果集、语句和/或连接对象,并确保在
finally
块中关闭它们



查看内存转储,我希望您关心898527228字节的去向。绝大多数由id为
2aab07855e38
的终结器对象保留。如果仍有转储文件,请查看该
终结器所指的内容。它看起来比Proxool对象问题更大。

这个“图像”链接指向的是你的twitter个人资料。@R.MartinhoFernandes我认为它指向他在twitter上托管的图像。选项4-避免使用(过度)使用终结器的库。选项1的变体)问题可能是终结器线程的原因。一个类重写finalize方法,导致Finalizer线程死锁如果您在finalize中有一个死锁的对象,那么除了修复错误或使用另一个库之外,您什么也做不了。这不是你可以从外部解决的问题。我注意到,在Android上使用大量regexp Pattern/Matcher实例(使用后立即发布)时,我会遇到这种情况,当我的内存用完时,我看到堆的50%被指向我的Pattern或Matcher实例的finalizerreference占用(堆映射中不存在对这些对象的其他引用)。