解决java内存泄漏问题:终结? [英] Troubleshooting a java memory leak: finalization?

查看:164
本文介绍了解决java内存泄漏问题:终结?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看似泄漏的行为不当的应用程序。在简要的探查器调查之后,大多数内存(80%)由 java.lang.ref.Finalizer 实例保存。我怀疑终结器无法运行。

I have a misbehaving application that seems to leak. After a brief profiler investigation, most memory (80%) is held by java.lang.ref.Finalizer instances. I suspect that finalizers fail to run.

这种情况的一个常见原因似乎是终结者抛出的异常。但是, Object 类的 finalize 方法的javadoc(参见这里例如)似乎自相矛盾:它陈述

A common cause of this seems to be exceptions thrown from the finalizer. However, the javadoc for the finalize method of the Object class (see here for instance) seems to contradict itself: it states


如果finalize方法抛出未捕获的异常,则忽略该异常并终止该对象的终止。

If an uncaught exception is thrown by the finalize method, the exception is ignored and finalization of that object terminates.

但稍后,它还声明


finalize方法抛出的任何异常都会导致最终化要暂停的对象,否则将被忽略。

Any exception thrown by the finalize method causes the finalization of this object to be halted, but is otherwise ignored.

我应该相信什么(即终止或不结束?),你是否有任何关于如何调查此类问题的提示?泄漏?

What should I believe (i.e., is finalization halted or not?), and do you have any tips on how to investigate such apparent leaks?

谢谢

推荐答案

我的第一步是建立这是否是真正的内存泄漏。

My first step would be to establish whether this is a genuine memory leak or not.

前面答案中提出的要点都与收集对象的速度有关,而不是你的对象是否被收集的问题所有。只有后者是真正的内存泄漏。

The points raised in the previous answers all relate to the speed at which objects are collected, not the question of whether your objects are collected at all. Only the latter is a genuine memory leak.

我的项目存在类似的困境,并以慢动作模式运行应用程序以确定我们是否有真正的泄漏。我们可以通过减慢输入数据流来实现这一点。

We had a similar predicament on my project, and ran the application in "slow motion" mode to figure out if we had a real leak. We were able to do this by slowing down the stream of input data.

如果在慢动作模式下运行时问题消失,则问题可能是在前面的答案中建议的那些,即Finalizer线程不能足够快地处理终结器队列。

If the problem disappears when you run in "slow motion" mode, then the problem is probably one of the ones suggested in the previous answers, i.e. the Finalizer thread can't process the finalizer queue fast enough.

如果这是问题,听起来你可能需要做一些非平凡的重构,如页面 Bringer128链接到,例如

If that is the problem, it sounds like you might need to do some non-trivial refactoring as described in the page Bringer128 linked to, e.g.


现在让我们看看如何编写需要事后清理的类,以便他们的用户不会遇到之前概述的问题。这样做的最好方法是将这些类拆分为两个 - 一个用于保存需要事后清理的数据,另一个用于保存其他所有 - 并且仅在前者上定义终结器

Now let's look at how to write classes that require postmortem cleanup so that their users do not encounter the problems previously outlined. The best way to do so is to split such classes into two -- one to hold the data that need postmortem cleanup, the other to hold everything else -- and define a finalizer only on the former

这篇关于解决java内存泄漏问题:终结?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆