在Java中,你不能真正“泄漏内存”,除非你:
- 实习生字符串
- 生成类
- 泄漏 JNI 调用的本机代码中的内存
- 在某个被遗忘或晦涩的地方保留你不想看到的事物的引用。
我认为你对最后一种情况感兴趣。常见方案包括:
- 侦听器,尤其是使用内部类完成的侦听器
- 缓存。
一个很好的例子是:
- 构建一个Swing GUI,可以启动可能无限数量的模式窗口;
- 让模式窗口在初始化期间执行如下操作:
StaticGuiHelper.getMainApplicationFrame().getOneOfTheButtons().addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ // do nothing... } })
注册的操作不执行任何操作,但它会导致模式窗口永远在内存中徘徊,即使在关闭后,也会导致泄漏 - 因为侦听器永远不会被取消注册,并且每个匿名内部类对象都持有对其外部对象的引用(不可见)。更重要的是 - 从模式窗口引用的任何对象也有可能泄漏。
这就是 EventBus 等库默认使用弱引用的原因。
除了听众之外,其他典型的例子是缓存,但我想不出一个好例子。
“在计算机科学中,内存泄漏(或在这种情况下的泄漏)发生在计算机程序消耗内存但无法将其释放回操作系统时。(维基百科)
简单的答案是:你不能。Java 执行自动内存管理,并将释放您不需要的资源。你无法阻止这种情况的发生。它将始终能够释放资源。在具有手动内存管理的程序中,这是不同的。你可以使用malloc()在C中获取一些内存。要释放内存,您需要 malloc 返回的指针,并在其上调用 free()。但是,如果您不再有指针(覆盖或超过生存期),那么不幸的是,您无法释放此内存,因此存在内存泄漏。
到目前为止,所有其他答案在我的定义中都不是真正的内存泄漏。它们都旨在用毫无意义的东西真正快速地填充记忆。但是,在任何时候,您仍然可以取消引用您创建的对象,从而释放内存→没有铅。acconrad的答案非常接近,尽管我不得不承认,因为他的解决方案实际上是通过强制垃圾收集器在无休止的循环中“崩溃”垃圾收集器)。
很长的答案是:通过使用JNI为Java编写一个库,你可以得到一个内存泄漏,JNI可以手动管理内存,因此有内存泄漏。如果调用此库,Java 进程将泄漏内存。或者,您可能在 JVM 中存在错误,从而导致 JVM 丢失内存。JVM中可能存在错误,甚至可能有一些已知的错误,因为垃圾回收并不是那么微不足道,但它仍然是一个错误。根据设计,这是不可能的。您可能要求一些受此类错误影响的Java代码。对不起,我不知道一个,无论如何,在下一个Java版本中,它很可能不再是一个错误。
-
Java 性能分析、性能调优和内存分析练习 我即将使用对Java应用程序进行研讨会分析,性能调优,内存分析,内存泄漏检测等。我需要一组练习,我可以尽可能地提供给参与者:使用该工具来分析发现问题:瓶颈,内存泄漏,次优代码等
-
-
HttpClient 内存管理 我有一个应用程序,它有一个线程池(ThreadPoolExecutor),它被赋予任务,每个任务执行一个HttpGet操作,并将InputStream读入一个字节[]来做一些事情。 在阅读了 HttpClient 文档之后,我得出的印象是
-
-
1 MB 或更大的 Java 字节数组占用两倍的 RAM 在Windows 10 / OpenJDK上运行以下代码11.0.4_x64生成为输出和。这意味着 100 万个元素的 200 字节数组占用大约 200MB RAM。一切都很好。 使用visualvm更深入地观察,在第一种情况下,我看到一切都符合