如何销毁Java对象?
如何销毁Java对象?
我使用了多个对象关系开发了一个Java应用程序,这使得内存使用太昂贵。由于应用程序设计使得销毁对象并重新利用之前清除的空间变得困难,我没有管理Java内存的经验。例如,我使用了观察者和MVC模式。根据理论,如果一个对象不可从任何活动线程或任何静态引用访问,它将成为垃圾回收或GC的候选对象。换句话说,如果一个对象的所有引用都为空,它将变得可进行垃圾回收。然而,在我短暂的经验中,销毁我想要从内存中删除的对象的所有引用非常困难(例如,当关闭一个窗口时),特别是在像我这样的场景中,你不知道有多少引用指向你的类。在这种情况下,当一个对象有多个引用时,我该如何处理对象的销毁?或者当引用相互复杂时,我需要如何管理内存?
问题的出现原因:
- 当我们不再需要一个Java对象时,为了释放内存空间,我们需要告诉垃圾回收器(Garbage Collector, GC)将其销毁。然而,有时候即使我们不再需要一个对象的引用,它仍然被保留在内存中,因为其他对象仍然引用它。这会导致内存泄漏,从而降低程序的性能和效率。
解决方法:
- 一种解决方法是将不再需要的引用赋值为null
。这样一来,垃圾回收器会将其标记为可回收的对象,并在合适的时候进行回收。通过将引用设置为null
,我们告诉垃圾回收器该对象不再被使用,可以释放其占用的内存空间。
- 同样的方法也适用于包含正在运行的线程对象或Timer的对象。当我们不再需要这些对象时,首先需要停止或取消其相关的线程或计时器。然后,将对这些对象的引用赋值为null
,以便垃圾回收器可以正确回收它们。
通过将不再需要的引用赋值为null
,我们可以帮助垃圾回收器正确销毁Java对象,从而释放内存并提高程序的性能和效率。
如何销毁Java对象?
当有多个引用指向对象时,如何处理对象的销毁?
确保这些引用不再需要。
即使在一个大的孤立的不再连接到主程序的未使用对象图中,如果你使它们隔离,它们都符合垃圾回收的条件。
已经超出作用域的局部变量将符合垃圾回收的条件(它们包含的对象也是如此),如果它们没有与其他任何东西关联(添加到集合、复合对象等)。对于UI对象来说,由于对象图可能难以理解,因此请确保正确处理它们,或者阅读文档以确保它们能够自然地被处理。
你无法"管理"内存,你只能管理引用。你可以通过不再有对它们的引用来"切断"与对象的连接。只要没有对它们的引用,它们就会一直存在于内存中,直到垃圾回收器销毁它们。
不要试图干预垃圾回收器来强制它执行某些操作。垃圾回收器是一种相当聪明的机制,虽然你可以尝试显式地要求它做出某些反应,但它可能会忽略你。这通常是一个坏主意:不要显式调用垃圾回收器,避免使用finalizers和显式置空,除非你理解它们的影响。
将一个被添加到多个集合或复合对象中的引用设置为null并不会使其符合回收条件。通过这样做,你只是将一个引用置为null。
你需要从所有有引用指向该对象的列表或容器中删除该对象(基本上是让它们"忘记"这个对象)。一旦没有任何对象"记住"或"链接"到你创建的对象,它就成为垃圾回收器图中的一个单独的项,这使得它成为一个待删除的候选项。
也许这听起来很繁琐,但如果你从手动管理内存的语言(如C或C++)来思考,释放和置空指向动态分配对象的指针确实会销毁它们,但你仍然需要从列表(或任何容器)中删除元素,否则它们会对一个空指针来说就像是空桶。
进一步阅读:
- 垃圾回收(特别是关于可达性的部分)
- Sun Microsystems的Java HotSpot虚拟机白皮书(日期有点旧,但非常好)
- Java理论与实践:垃圾回收的简要历史-垃圾回收是如何工作的?
- Java理论与实践:垃圾回收性能
- Java垃圾回收的工作原理
- 处理Java程序中的内存泄漏
- 从Java代码到Java堆
- Stack Overflow上关于Java内存的问题
- Java内存管理的最佳实践
明白了!但是...当一个对象可能被添加到多个ArrayList中时,我该如何将其隔离?设置object = null
会移除所有引用吗?
不,不会。那只会将当前作用域中名为object
的引用置为null。你确实需要从所有列表或任何其他容器中删除这个对象。
多个ArrayList的生命周期是短暂的还是长期的?如果是短暂的,那么就没有问题。在ArrayList不再可达之后,垃圾回收器会发挥作用。如果ArrayList的生命周期很长,除非你做些什么,否则在其生命周期内所有元素都将可达。我建议使用短暂的ArrayList。
是的,但是短暂的一面已经在我的回答中提到了:局部对象将符合垃圾回收的条件,它们包含的引用也将如此。这是引用计数的多米诺骨牌效应。
因为你似乎是Stack Overflow的新用户...如果这个答案(和其他答案)对你有帮助并回答了你的问题,你应该为它们点赞(使用每个答案左侧的向上箭头)并接受最正确回答你问题的答案(使用每个答案左侧的"√"符号)。不是说你现在就要这样做,你可以给自己时间作出决定,等待更多的答案,当然。
谢谢大家!我明白了 🙂
这确实是一个非常详细的答案。我希望我可以将其标记为收藏,但只能收藏问题 =\。
谢谢。很高兴你喜欢它。