java - >的System.gc();这个调用是否会打开一个新线程?

时间:2010-04-19 12:19:10

标签: java concurrency garbage-collection multithreading sequential

例如我这样的代码

... 获取一些内存并丢失所有指向该内存的指针,以便System.gc();可以收集它。

致电System.gc();

做一些其他任务;


这里做“做其他一些任务;”和“System.gc();”在paralel工作或做“做一些其他任务;”等待“System.gc();”待执行

谢谢

9 个答案:

答案 0 :(得分:7)

您可能不应该使用System.gc()。 C / C ++用户遇到java的一个常见误解是他们认为他们需要告诉虚拟机何时可以执行垃圾收集。实际情况是垃圾收集器经过高度优化,并且在最好的情况下自行执行此任务。通常不建议调用System.gc()。

如果您确实调用System.gc(),它将“建议”系统执行垃圾收集。它通常不会实际执行集合。如果它在另一个线程中运行取决于实际的收集算法。默认设置将在运行时阻止所有内容。所以它可以在不同的线程中运行,但它会阻止你当前的执行。

答案 1 :(得分:6)

这里的确切行为完全取决于JVM实现。在规范中(这是正确的JVM实现需要为您提供的),它可以并行发生,它可以在代码执行之前发生,或者根本不会发生。

在实践中,我对JVM的观察结果是我在一个单独的线程中立即运行。但是,在某些情况下,多个调用会产生多个线程,有时它会在一个线程上对请求进行排队。启动的垃圾收集始终是“停止世界”类型(即它非常完整,缓慢或暂停应用程序)。

但是,鉴于您对@Chris Dail的评论,您的基本问题不是System.gc()调用的行为。调用System.gc()可以有一些用途。它可以用于清晰的内存,因此您可以了解应用程序的占用空间当前有多大。它还可以用作一种策略,以确保更早发生世界各地的垃圾收集,以便在更短的时间内“停止世界”,因为需要清除更少的内存。 (我应该注意到,随着JVM变得越来越复杂,这种事情变得越来越不必要了,实际上会产生适得其反的效果)。

然而,

它没有做的是以任何方式解决OutOfMemoryError。 JVM在它尽可能地收集垃圾之前不会给你一个OutOfMemoryError。调用System.gc不会改变它。如果你有一个OutOfMemoryError,很可能是因为你以你真正不需要的方式持有对象的引用,但这会阻止那些对象的内存被回收。

答案 2 :(得分:4)

它通常是同步的,但不能保证。

实际上既不能保证集合能够有效地发生,因为JVM将决定它是否有意义以及使用什么样的垃圾收集。

如果您需要其他信息,可以使用-verbosegc标志启动您的程序..

在任何情况下,垃圾收集都是由JVM自动发出的,没有任何指定的调用,调用System.gc()只是一个提示,让它知道它可能会启动一个集合。

答案 3 :(得分:1)

如何执行垃圾收集取决于JVM实现。通常的实现可能会停止所有线程,全局收集内存,例如,只停止一个线程收集本地线程的内存。阅读Sun以及旧版article中的垃圾收集的更多信息。

答案 4 :(得分:1)

正如Eric Eijkelenboom所指出的那样,调用此方法并不意味着垃圾收集器会立即执行。实际上你根本不知道它是否会被调用......

在你的情况下(根据对Amarghosh的答案的评论来判断)你需要释放一些内存,然后才能做一些需要大量内存的东西吗?在这种情况下,您不必担心。如果有足够的内存进行垃圾回收,那么当您尝试分配它时,它将自动完成。

答案 5 :(得分:0)

“执行其他任务”等待System.gc()执行并返回。

答案 6 :(得分:0)

没有办法知道。调用System.gc()并不意味着在那第二次执行垃圾收集,它只是被安排。 JVM可以在适当的时候执行垃圾收集。

答案 7 :(得分:0)

javadoc告诉http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#gc(): “当控制从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间。

所以我会说“做其他一些任务;”等待“System.gc();”被执行!

没有使用并行性 - 这对Java应用程序来说并不好。事实上,调用/强制垃圾收集器永远不是一个好主意。它必须保留到极端情况下,没有其他解决方案...

再见 阿尔

答案 8 :(得分:0)

根据Java规范,调用 System.gc()的线程将停止,直到GC完成其操作。请注意,这只是一个提示,JVM可以自由地忽略它,而Sun的JVM实际上有一个命令行开关(-XX:-DisableExplicitGC)。使用此开关,System.gc()不执行任何操作并立即返回。

无论哪种方式,规范中的任何内容都不会阻止其他线程运行。这取决于GC算法; Sun的JVM包括几个,其中一些能够与大多数工作的应用程序线程同时运行。

正如其他人所指出的,在大多数情况下,明确调用System.gc()的净效应是降低性能。如果你觉得你必须调用那种方法,那么你可能会做错事。