Java中是否存在内存泄漏?

jav*_*guy 33 java memory memory-leaks memory-management

我多次问这个问题.什么是回答的好方法

Ste*_*n C 21

Java中可能存在内存泄漏吗?

答案是它取决于你所谈论的内存泄漏类型.

当应用程序忽略它freedispose对象完成它时会发生经典的C/C++内存泄漏,并且它会泄漏.循环引用是这种情况的子案例,其中应用程序很难知道何时对free/ dispose而忽略了这样做.相关问题是应用程序在释放后使用对象或尝试将对象释放两次.(你可以把后面的问题称为内存泄漏,或者只是错误.无论哪种方式......)

Java和其他(完全1)托管语言大多不会遇到这些问题,因为GC负责释放不再可访问的对象.(当然,悬空指针和双重自由问题不存在,并且循环不会有问题,因为它们适用于C/C++"智能指针"和其他引用计数方案.)

但在某些情况下,Java中的GC会遗漏那些(从程序员的角度来看)应该被垃圾收集的对象.当GC无法确定无法访问对象时,会发生这种情况:

  • 程序的逻辑/状态可能使得不会发生使用某些变量的执行路径.开发人员可以看到这一点很明显,但GC无法确定,并且谨慎(因为它是必需的).
  • 程序员可能错了,GC正在避免可能导致悬空引用的问题.

(请注意,Java中内存泄漏的原因可能很简单,也可能非常微妙;请参阅@ jonathan.cone的一些微妙的答案.最后一个可能涉及外部资源,您不应该依赖GC来处理. )

无论哪种方式,你都可能遇到不需要的对象无法被垃圾收集的情况,并且在内存中占用内存......内存泄漏.

然后是Java应用程序或库可以通过需要手动管理的本机代码分配堆外对象的问题.如果应用程序/库有错误或使用不当,您可能会收到本机内存泄漏.(例如:Android Bitmap内存泄漏 ...注意到此问题已在Android的更高版本中得到修复.)


1 - 我暗指几件事.某些托管语言允许您编写非托管代码,您可以在其中创建经典存储泄漏.一些其他托管语言(或更准确地说是语言实现)使用引用计数而不是适当的垃圾收集.基于引用计数的存储管理器需要一些东西(即应用程序)来打破周期......否则会发生存储泄漏.


Mar*_*son 10

是.即使您有GC,仍可能发生内存泄漏.例如,您可能会保留必须手动关闭的数据库结果集等资源.


小智 10

好吧,考虑到java使用垃圾收集器来收集未使用的对象,你不能有一个悬空指针.但是,您可以将对象保留在范围内的时间超过其需要的时间,这可能被视为内存泄漏.更多相关信息:http://web.archive.org/web/20120722095536/http : //www.ibm.com : 80/ developerworks/ rational/ library/05/ 0816_GuptaPalanki/

你正在考试这个什么的吗?因为那里至少有一个A +.


jon*_*one 5

答案是肯定的,但这通常是编程模型的结果,而不是JVM中某些缺陷的指示.当框架的生命周期与正在运行的JVM不同时,这种情况很常见.一些例子是:

  1. 重新加载上下文
  2. 未能取消引用观察者(听众)
  3. 使用完毕后忘记清理资源*

* - 已经解决了数十亿美元的咨询费用