如何将对象标记为由 GC(垃圾收集器)进行垃圾收集?

发布于 2024-10-23 22:24:43 字数 109 浏览 2 评论 0原文

在Java中,有没有一种方法可以在下一个清理周期中标记一个对象以供GC进行垃圾回收?

我听说将对象设置为 null 不再有效。

In Java, is there a way to mark an object for garbage collection by the GC, during its next clean up cycle?

I've heard that setting an object to null no longer works.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

挽清梦 2024-10-30 22:24:43

不,你不能。如果另一个变量引用了它,您会期望发生什么?

请注意,您不能将对象设置为null - 您只能将变量设置为null。如果另一个变量仍然拥有对该对象的引用,它仍然不符合垃圾回收的条件。

如果您认为需要这样做,这可能意味着您误解了您的数据 - 或者您的代码中的某个地方可能存在泄漏(例如,您只添加条目的列表,由静态变量引用 - 这些条目当类加载器处于活动状态时,永远没有资格进行垃圾收集)。

每个 JVM 都有自己的 GC,但在 Hotspot 中,下次 GC 在该对象当前“生存”的一代上运行时,该对象将被垃圾收集(假设它没有终结器,这会使事情变得复杂)。如果该对象位于“年轻”一代,那么这可能很快就会发生 - 如果它位于“老”一代,则可能需要更长的时间。

您可能需要查看Java 6 GC 调优文档 了解更多信息,当然,从那时起,OpenJDK 7 等的情况已经发生了变化。

No, you can't. What would you expect to happen if another variable had a reference to it?

Note that you can't set an object to null - you can only set a variable to null. If another variable still has a reference to the object, it will still not be eligible for garbage collection.

If you think you need to do this, that probably means you're misinterpreting your data - or that you may have a leak somewhere in your code (e.g. a list which you only ever add entries to, referenced by a static variable - those entries will never be eligible for garbage collection while the classloader is alive).

Each JVM has its own GC, but in Hotspot an object will be garbage collected next time the GC runs over the generation that object currently "lives" in (assuming it doesn't have a finalizer, which complicates things). If the object is in a "young" generation, that will probably happen quite soon - if it's in an "old" generation it may well take longer.

You may want to see the Java 6 GC tuning documentation for more information, although of course things have moved on since then for OpenJDK 7 etc.

沩ん囻菔务 2024-10-30 22:24:43

我知道这个问题已经得到解答,但是有一些方法可以操纵 Java 垃圾收集器查看引用的方式。您可以通过软引用、弱引用和幻像引用来做到这一点。看一下 java.lang.ref package 以获得更好的解释。

还有一个 很好的示例,用于确定 PhantomReference 何时将被垃圾收集:

幻像引用用于确定对象何时即将被回收。使用幻像引用比终结更安全,因为一旦对象幻像可达,就无法复活。

// Create the phantom reference.
ReferenceQueue rq = new ReferenceQueue();
PhantomReference pr = new PhantomReference(object, rq);

// Wait until the object is about to be reclaimed.
try {
    while (true) {
        Reference r = rq.remove();
        if (r == pr) {
            // The object is about to be reclaimed.
            // Clear the referent so that it can be reclaimed.
            r.clear();
        }
    }
} catch (InterruptedException e) {
}

I know this question has been answered, but there are ways you can manipulate the way that the Java Garbage collector looks at your references. You can do this through Soft References, Weak References, and Phantom References. Take a look at the java.lang.ref package for a better explanation.

Also here's a nice sample to determine when a PhantomReference is about to be garbage collected:

A phantom reference is used to determine when an object is just about to be reclaimed. Phantom references are safer to use than finalization because once an object is phantom reachable, it cannot be resurrected.

// Create the phantom reference.
ReferenceQueue rq = new ReferenceQueue();
PhantomReference pr = new PhantomReference(object, rq);

// Wait until the object is about to be reclaimed.
try {
    while (true) {
        Reference r = rq.remove();
        if (r == pr) {
            // The object is about to be reclaimed.
            // Clear the referent so that it can be reclaimed.
            r.clear();
        }
    }
} catch (InterruptedException e) {
}
り繁华旳梦境 2024-10-30 22:24:43

Java 垃圾收集器采用标记和清除方法。这意味着从已知仍在使用的对象开始,所有引用都会被跟踪,并标记以这种方式访问​​的对象。这样,根本没有引用的对象就不会被标记,并且应该确保被删除。因此,您可以确保删除对此对象的所有引用,以便在垃圾收集器的下一轮中,该项目被删除。

此外,您可以用来

Runtime.getRuntime().gc();

指示垃圾收集器应该运行。注意:您无法确定它是否真的运行。

The Java Garbage Collector works with a mark and sweep method. This means from object that are known to still be in used all references are followed and the objects that are visited in that way are marked. In that way objects with no references at all are not marked and should be sure to be deleted. So you could ensure that all references to this object are removed, so that in the next turn of the Garbage Collector, the item is deleted.

Additionally you could use

Runtime.getRuntime().gc();

to indicate that the Garbage Collector should run. Note: you can't be sure that it really runs.

烦人精 2024-10-30 22:24:43

你听错了,但话又说回来,描述也是错误的。

您不是将对象设置为 null,而是将变量设置为 null。如果该变量可用于获取对象,则该变量具有对该对象的引用。将变量设置为 null 与变量“丢失对对象的引用”相同。

一旦 Java 检测到正在运行的程序无法访问某个对象或一组对象,它就会从内存中删除这些对象。它不会更快地将它们从内存中删除,因为如果这样做了,并且程序的其他部分尝试使用对该对象的引用,那么该引用将以 Java 中不允许的方式失败。

诀窍是不要只设置一个对 null 的引用,您必须设置所有可能对 null 的引用。这就是为什么每次创建新引用时都要考虑这一点很重要,因为您希望以最终会被清除的方式创建它们(除非您想要内存泄漏)。

You heard wrong, but then again the description is wrong too.

You don't set an object to null, you set a variable to null. If the variable can be used to get to an object, then the variable has a reference to the object. Setting the variable to null is the same as the variable "losing the reference" to the object.

Once Java detects that an object, or a group of objects can't be reached by the running program, it will remove those objects from memory. It won't remove them from memory one moment sooner, because if it did, and some other part of the program tried to use a reference to the object, then the reference would fail in a way that's not permissible in Java.

The trick is not to set just one reference to null, you have to set all the references that might have been made to null. That's why it's important to consider each time you create a new reference, because you want to create them in such a manner that they will eventually be cleared (unless you want a memory leak).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文