垃圾多久收集一次?我认为我的对象没有被删除
Posted
技术标签:
【中文标题】垃圾多久收集一次?我认为我的对象没有被删除【英文标题】:How frequently is garbage collected? I don't think my objects are being deleted 【发布时间】:2012-08-13 00:32:22 【问题描述】:如果我有一个类删除自己,它的内部方法是否应该停止执行?我有一个 B 类,它告诉 A 类从 A 的 ArrayList 中删除 B。我相当肯定 B 只存在于 A 的 ArrayList 中,所以当我删除它时,它应该被删除,对吗? (注意:我已经包含了一个 Serializable 实现,以防万一这与 VM 如何处理我的类有关,但我没有在这里写入 read- 和 writeObject 方法。我怀疑它与不过这个问题。)
public class A implements Serializable, B_Listener
ArrayList<B> bArray;
public A()
bArray = new ArrayList<SomeObject>();
bArray.add(new B(bArray.size(), this));
@Override
public void deleteAtIndex(int index)
bArray.remove(index);
public class B implements Serializable
B_Listener listener;
int index;
public B(B_Listener listener, int index)
this.listener = listener;
this.index = index;
//This is called at some point in a B's lifetime.
private void selfDestruct()
listener.deleteAtIndex(index);
Log.w("B.class", "Should this not output? It does.");
public interface B_Listener
public void deleteAtIndex(int index);
所以当我不相信它应该执行 Log.w 消息时。因此,恐怕我正在创建 java 的内存泄漏。我查看并查看了整个代码,试图找到 B 可能被指针保存的位置,但除了我想要的之外,我什么也没想到。
那么我问的是垃圾收集的时间是否与我最终删除 B 的时间不同。如果是这种情况,那么暂时可以肯定地说我实际上并没有持有我不打算持有的物品吗?
额外(注意:这可能很难理解,上面的所有内容都足以解决问题): 我也用 android-Views 标记了它,因为我正在 Android 上开发:我的 B 类包含指向 B 作为侦听器的 View 对象。我相信当我删除视图时,视图管理器或任何 Android 都不应再指向视图,当我删除 B 时,它的所有内部视图也应该被删除,这意味着它们不能再通过自己的侦听器来保持 B 的存在指针。我只是说出来看看我的理解是否正确。
【问题讨论】:
谁在打电话给B.selfDestruct()
?
你是在问为什么“selfDestruct”的第二行在第一行之后仍然执行? (为什么不应该?)FWIW 垃圾收集对您的应用程序应该是完全不可见的,并且根本不会干扰其行为。它所做的只是确保有足够的内存可用。不要试图与之互动。
B 有多个状态,因此如果 B 发现自己处于表明它无用的状态,它会调用 selfDestruct()。在我的实际代码中,没有 selfDestruct 方法,而是我构建的状态处理程序(在 B 内)只执行行 listener.deleteAtIndex(index)。我不想与垃圾收集进行交互。我试图理解它。我没有学过 Java,我学过 C++。
【参考方案1】:
当然不是。
只有在return
s、抛出异常或线程被中止时,方法才会“停止执行”。
垃圾收集的全部意义在于它对您来说是不可见的。除非有特殊技巧(例如 WeakReferences 或检查空闲内存),否则无法判断一个对象是否已被垃圾回收 - 如果您可以检查它是否存在,则意味着您有对它的引用,所以它 无法收集。
【讨论】:
特别是,this
无法在其方法之一仍在运行时进行垃圾收集。至少,调用当前方法的对象仍然有对该对象的引用(在方法调用完成并且堆栈展开后,该引用可能会消失,但之前不会)。
谢谢你们!这是我需要听到的。我曾认为垃圾收集是即时的。不幸的是,由于我是新人,所以我不能赞成您的回答:(
我只想指出,SLaks 正在回答我在这篇文章正文中提出的问题,供以后阅读本文的人使用。
顺便说一句,一个对象何时有资格被 GC 和它实际被收集是有区别的。 GC 通常不会收集对象,直到它需要——也就是说,直到它用完空间(我在这里画了一点粗刷)。这让它可以批量 GC,速度更快(以使用更多 RAM 为代价)。【参考方案2】:
通常会有两种 GC:次要(每秒左右)和主要(每隔一小时左右,但如果您为 VM 提供足够的内存,也可能是一周)。
对象以异步方式释放(批量执行此操作更有效,并且有助于保持内存不碎片化)。它们在不可访问的毫秒内不会被删除。
垃圾收集只有在没有活动的线程 能够访问对象时才有意义,而不是在没有对象 持有对它的引用时才有意义。在您的代码中,只要 selfDestruct 运行,线程就拥有一个隐式的“this”引用。这实际上会导致对象被线程引用 - 并且不受 GC 影响。
【讨论】:
谢谢,这强化了上面的答案,加深了我对 GC 的理解。以上是关于垃圾多久收集一次?我认为我的对象没有被删除的主要内容,如果未能解决你的问题,请参考以下文章