2

有人可以给我一些建议吗?我正在阅读一篇旧文本和我老师的一些笔记,当在 Java 中使用多线程时,有必要编写一个特殊的垃圾收集程序。

这仍然适用于 Java SE6 及更高版本吗?如果确实如此,有人可以提供执行此操作的标准方法。

4

5 回答 5

2

据我所知,只要没有任何东西指向一个对象,垃圾收集器就会释放该对象。

Java 的垃圾收集器在循环引用方面非常健壮,我不明白为什么它不适用于同时运行的多个线程。

因此,您可以放心地假设您不需要为垃圾收集编写特殊的程序,因为 java 会非常有效地为您完成。

如果要在 java 中释放对象,只需确保没有变量引用您的对象。(包括来自 java 集合或其他库的结构(列表、数组等))

于 2012-06-18T17:26:55.587 回答
2

使用垃圾收集器可以更轻松地编写多线程代码。这是因为在多线程上下文中手动释放资源很难做到正确。使用 GC,您大部分时间都无需担心。

我正在阅读,当使用多个线程时,有必要编写一个特殊的垃圾收集程序。

我不相信这种情况曾经发生过。

这是否仍然适用于 SE6 及更高版本,如果是,是否有标准方法可以做到这一点。

执行此操作的标准方法是不引用您不需要的对象。例如,如果你有一个不需要的局部变量,就让它脱离作用域。

它不必很复杂。

于 2012-06-18T18:25:12.343 回答
1

这篇来自JavaWorld 2003 年的文章,J2SE 1.4.1 增强了垃圾收集,对 J2SE 1.4.1 之前的 Java 垃圾收集有这样的说法:

Mark and sweep 是一种“stop-the-world”的垃圾收集技术;也就是说,所有应用程序线程都会停止,直到垃圾收集完成,或者直到更高优先级的线程中断垃圾收集器。如果垃圾收集器被中断,它必须重新启动,这可能导致应用程序崩溃而没有明显的结果。标记和扫描的另一个问题是许多类型的应用程序不能容忍它的停止世界特性。对于需要近乎实时行为的应用程序或为大量面向事务的客户端提供服务的应用程序尤其如此。

Dobbs 博士 2009 年的一篇文章G1: Java's Garbage First Garbage Collector对 SE 6 之前的 Java 垃圾收集器有这样的说法。

直到最近,Java SE 还提供了两个主要的收集器:并行收集器和并发标记清除 (CMS) 收集器——请参阅侧边栏的并行性和并发性。在最新的 Java SE 6 更新版本中,G1 收集器是另一种选择。G1 的计划是最终将 CMS 替换为低暂停、软实时收集器。让我们来看看它是如何工作的。

因此,在 SE 6 之前,一些有助于 Java 垃圾收集的额外预防措施可能会有所帮助,尤其是对于具有大量临时变量的多线程应用程序,这些临时变量会生成需要收集的垃圾。然而,这应该最多需要在慢速期间显式调用垃圾收集器。写一些特别的东西似乎很不寻常。

但是,情况比以前要好得多。此外,垃圾收集在不同版本的 Java 虚拟机之间可能会有所不同。

所以几年前可能是真的,现在用现在的技术几乎肯定不是真的。

这篇文章,如何监控 Java 内存使用情况?,讨论了监视 Java 内存使用情况以及显式调用垃圾收集器的一些优缺点。

Oracle 有一个涵盖 Java SE 7 Hotspot JVM的Java Garbage Collection Basics 教程。

于 2016-06-09T02:43:37.443 回答
0

使用以下代码显式调用垃圾收集器

Runtime runtime = Runtime.getRuntime(); 
runtime.gc();

但这不是必需的,jvm 会自动处理正确及时运行的 GC。

于 2012-06-18T17:38:51.683 回答
0

几乎可以肯定,您的讲师的说明(正确地)指出,由于 Java 是一个多线程环境,因此在 Java 运行时环境中实现垃圾收集器时需要比仅涉及单个线程时需要更多的注意。任何多线程环境 都是如此。

正如其他人所说,程序员看不到任何这种复杂性。这是 gc 提供的自动内存管理的礼物。

于 2012-06-18T17:58:13.953 回答