好吧,我开发了一个使用多个对象关系的java应用程序,这使得内存使用过于昂贵。我没有管理java内存的经验,因为应用程序设计很难破坏对象并重新利用先前清除的空间。例如,我正在使用Observer和MVC模式。
所以,理论说......
如果没有,则对象有资格获得垃圾收集或GC 可以从任何活动线程或任何静态引用访问
换句话说,如果一个对象的所有引用都为null,则可以说该对象符合垃圾收集的条件。
但是,在我的短暂经历中,当我有一个类似我的场景时,我很难破坏我想要从内存中移除的对象的所有引用(例如,当一个帧关闭时)知道你的课程有多少引用。
根据这个上下文,当有多个引用时,如何处理对象破坏?或者当你有一个复杂的参考对象时,我怎么需要管理内存?
答案 0 :(得分:17)
根据这个上下文,当有多次引用时,如何处理对象破坏?
确保不再需要这些引用。
如果你将它们隔离开来,即使在一个大的孤立图表中,未使用的对象已经不再与你的主程序连接,那么它们都有资格进行垃圾收集。
已达到其范围末尾的局部变量将有资格进行垃圾收集(以及它们包含的对象),如果它们尚未“链接”到任何其他对象(添加到集合,交互式等等)。 ..)。对于在对象图方面确实难以推理的UI对象,请确保正确处理它们或阅读文档以确保它们自然处理掉。
或者当您对彼此有复杂的引用时,如何管理内存?
你不能“管理”记忆。您可以简单地管理参考。我们的想法是通过简单地不引用它们来“严格”与对象的连接。然后他们会记住,直到GC消灭它们。
不要试图弄乱GC来强迫它做事。这是一个相当聪明的野兽,虽然你可以尝试指示它明确地对某些请求做出反应 - 它可能会忽略你 - 它是usually a bad idea:{{3 },避免终结者和do not invoke the GC explicitly explicit nulling。
简单地将 a 引用添加到已添加到多个集合或复合的对象中,将无法使其符合收集条件。通过这样做,if you don't understand their implications。
您需要从所有引用它的列表或容器中删除此对象(基本上,使它们“忘记”此对象)。一旦没有对象仍然“记住”或者与你创建的对象有“链接”,它就会成为垃圾收集器图中的一个孤独的项目,这使它成为删除的候选对象。
也许这听起来很乏味,但是如果你从一种手动管理内存的语言(C或C ++,以命名最明显的两个引用)中想到它,那么释放和归零动态分配对象的指针就会确实会破坏它们,但你仍然需要从列表(或任何容器)中删除元素,否则它们就像空桶一样显示为空指针。
答案 1 :(得分:6)
java垃圾收集的重点是你不必做任何事情。垃圾收集已经完成。
答案 2 :(得分:1)
将您希望GC收集的每个引用分配到null
。
答案 3 :(得分:1)
你能做的是做一个中级课。例如,如果你有A类的实例,你有很多引用并且你想删除它但是很多引用使它变得困难,你可以执行以下操作:创建类B的实例,其中只包含除了引用类A的实例(像某种代理)。现在您将有很多对B类实例的引用,但只有一个对A类实例的引用,您可以轻松删除它,垃圾收集器将收集A类实例。
图像显示使用代理时的差异(B类实例):现在只需删除一个引用。
答案 4 :(得分:0)
在大多数情况下,GC会在适当的时候做到这一点。
您可能会遇到一种情况,例如,视图正在观察模型,您想要抛弃视图但保留模型。在这种情况下,您需要记住观察者回调对象,并在丢弃视图时将其删除。您不必为每个观察者设置特殊字段 - 一组取消注册回调的任务都可以。或者,更复杂的是,您可以在模型上有一层瞬态间接,从底层解压缩。我建议用一种或另一种弱引用来避免奇怪的东西。
如果您可能有终结者(或需要某种弱映射驱逐),例如大概使用java.awt.Frame,您可能需要在资源和内存猪之间有一层间接,这可能只是被淘汰了。