本文分析一下可能引起java内存泄露的场景: 通过 finalize 方法 终结器finalizers的使用是潜在内存泄漏问题的另一个来源。每当类的 finalize 方法被重写时,该类的对象不会立即被垃圾回收。相反,GC将它们排队等待最后确定,这将在稍后的时间点发生。 另外,如果我们的应用程序不能更快地完成或最终处理一个错误,那么如果我们的应用程序不能更快地完成一个错误,那么我们的应用程序就不能完成。 为了证明这一点,让我们考虑一下,我们已经为一个类重写了 finalize 方法,并且该方法需要一点时间来执行。当此类的大量对象被垃圾回收时,在VisualVM中,它看起来像: 但是,如果我们只删除重写的 finalize 方法,则同一个程序会给出以下响应: 如何预防? 我们应该避免使用终结器 内部字符串 当Java 7从 PermGen 转移到 HeapSpace 时,Java字符串池经历了一次重大变化。但是对于在版本6及以下运行的应用程序,我们在处理大字符串时应该更加注意。 如果我们读取一个巨大的字符串对象,并在该对象上调用 intern ,那么它将进入字符串池,该池位于PermGen(永久内存)中,只要我们的应用程序运行,它就会一直留在那里。这会阻塞内存并在我们的应用程序中造成内存泄漏。 JVM 1.6中这个例子的PermGen在VisualVM中如下所示: 与此相反,在一个方法中,如果我们只是从文件中读取一个字符串,而不是对其进行内接,那么PermGen看起来像: 如何预防? ThreadLocal是一种构造,它使我们能够将状态隔离到特定线程,从而允许我们实现线程安全。 当使用这个结构时,每个线程都将持有一个对其ThreadLocal变量副本的隐式引用,并将维护自己的副本,而不是在多个线程之间共享资源,只要线程是活动的。 尽管 ThreadLocal 变量有很多优点,但是它的使用还是有争议的,因为如果使用不当,它们会导致内存泄漏。