理论上说,如果一个对象不可从任何活动线程或静态引用访问,则该对象将成为垃圾回收或GC的候选对象。换句话说,如果一个对象的所有引用都为空,则该对象将成为垃圾回收的候选对象。
但是,在我的短暂经验中,当你有像我这样的场景时(即你不知道你的类存在多少引用),从我想要从内存中删除的对象中销毁所有引用变得非常困难(例如,当关闭一个帧时)。
根据这种情况,当一个对象有多个引用时,我该如何处理它的销毁?或者在彼此之间具有复杂引用时,我需要如何管理内存?
根据这种情况,当有多个引用时,我该如何处理对象销毁?
确保这些引用不再需要。
如果您将它们隔离开来,即使是在一个大的孤立的图形中,这些未使用的对象不再与您的主程序连接在一起,那么它们都有资格进行垃圾回收。
如果局部变量已经到达其作用域的末尾(并且其包含的对象也是如此),则它们将有资格进行垃圾回收,如果它们没有与其他任何东西“链接”(添加到集合、复合等)。对于 UI 对象,在对象图方面确实很难理解,请确保正确处理它们或阅读文档以确保它们会自然地被处理。
当你的对象互相引用时,我需要如何管理内存?
你无法“管理”内存。你只能管理引用。思路是通过简单地不拥有对它们的引用来“切断”与对象的连接。这样它们会保留在内存中,直到GC将它们消除。
不要试图干预GC以强制它执行操作。它是一种相当聪明的机制,尽管你可以尝试指示它显式地响应某些请求,但它可能会忽略你,这通常是个坏主意:通常不要调用GC,避免使用finalizers和显式空值, 如果你不理解它们的影响。
简单地将一个已添加到多个集合或组合中的对象的引用设为null,并不能使其有资格被垃圾收集。这样做,你只会将一个引用设为空。
你需要从所有包含对该对象引用的列表或容器中删除此对象(基本上是使它们“忘记”关于该对象的信息)。一旦没有对象仍然“记得”或具有对你创建的对象的“链接”,它就成为了垃圾收集器图表中的一个孤独的项目,从而使它成为删除的候选项。
也许听起来很繁琐,但如果你从手动管理内存的语言(比如C或C++)的角度考虑,释放和设置指向动态分配对象的指针的值确实会销毁它们,但你仍然需要从列表(或任何容器)中删除元素,否则它们将像空桶一样出现在一个空指针中。
Java垃圾回收的整个意义在于你不需要做任何事情,垃圾回收会替你完成。
将您希望GC收集的每个引用分配给null
。
大多数情况下,垃圾回收器会在适当的时间内完成其任务。
有时您可能需要这样一种情况,即视图正在观察模型,您想要放弃视图但保留模型。在这种情况下,您需要记住观察器回调对象,并在丢弃视图时删除它们。您不一定需要为每个观察者设置特殊字段-一个取消注册每个回调的任务集将足够。或者,更复杂地,您可以具有在模型上方具有瞬态间接层,该层与底层一起解压缩。我建议避免使用各种奇怪的弱引用之类的东西。
在您可能具有终止器(或需要某种弱映射驱逐)的情况下,例如java.awt.Frame,您可能需要在资源和内存占用之间添加一层间接层,该层可以简单地被置空。